换种角度理解Java中synchronized同步锁
Synchronized关键字用于处理线程安全问题
基本语法为:Synchronized(线程共享的对象){
会出现线程安全问题的代码;
}
一个经典的线程安全问题:银行取款问题
//银行
class Bank{
private int money = 1000;
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
//取钱的人
class Person extends Thread{
public Bank money;
public Person(Bank money){
this.money = money;
}
public void run() {
getMoney(1000);
}
public void getMoney(int num) {
if(money.getMoney() >= num) {
money.setMoney(money.getMoney() - num);
System.out.println("取了:" + num);
}
}
}
//执行代码
public static void main(String[] args) {
Bank money = new Bank();
Person thread1 = new Person(money);
Person thread2 = new Person(money);
thread1.start();
thread2.start();
}
该代码的问题是:如果第一个线程A执行到if(money.getMoney() >= num)被另一个线程B抢走,那么当另一个线程B执行完之后,这个线程A会接着之前被中断的地方继续执行下去(保留现场,详细可翻阅操作系统书籍)。这时,由于线程不用继续判断if(money.getMoney() >= num)就可以继续执行下去,从而取款成功,所以就出现了线程安全问题。
这个时候,加上Synchronized关键字就可以完美解决:
public void run() {
synchronized (money) {
getMoney(1000);
}
}
其实,这个被一些线程共享的对象可以被想象为一把钥匙,而这些线程有且只有这一把钥匙,当一个线程执行到Synchronized时,会先占有这把钥匙,直到整个Synchronized代码块结束,这个钥匙才被拿出来重新被这些线程争夺

浙公网安备 33010602011771号