六.线程同步(并发)
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