六.线程同步(并发)

1.synchronized方法

控制对对象的访问,每个对象都有一把锁,每个synchronized方法都必须获得调用该方法的锁才能执行,方法一旦执行,就独享该锁,使用完该对象后释放锁,其他线程才能获得锁,继续执行。

public synchronized void method(){}

 

2.synchronized块

synchronized (obj){}

obj可以是任何对象,称为同步监视器,推荐使用共享资源作为同步监视器,synchronized方法无需指定同步监视器,因为其就是this。

执行过程:1.第一个线程访问,锁定同步监视器,执行内容 2.第二个线程访问,同步监视器被锁,无法访问,等待第一个线程解锁同步监视器然后访问。

点击查看案例
public class Unsafe2 {
    public static void main(String[] args) {
        Account account = new Account(200,"home");
        // 创建家庭账户一共有200w
        GetMoney boy = new GetMoney(account,200,"boy");
        GetMoney girl = new GetMoney(account,50,"girl");
        boy.start();
        girl.start();
    }
}

class Account{

    int money;
    String id;

    public Account(int money, String id) {
        this.money = money;
        this.id = id;
    }
}

class GetMoney extends Thread{

    Account account;
    int get;
    // 取了多少
    int now;
    // 现余多少

    public GetMoney(Account account, int get,String name) {
        super(name);
        this.account = account;
        this.get = get;
    }

    @Override
    public void run() {
        
        synchronized (account){
            if (account.money - get < 0){
                System.out.println(Thread.currentThread().getName()+":money is not enough");
                return;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            account.money = account.money - get;
            now = now + get;
            System.out.println(account.id+"-account-money:"+account.money);
            System.out.println(Thread.currentThread().getName()+"-now:"+now);
        }
    }
}
运行结果
home-account-money:0
boy-now:200
girl:money is not enough