Java并发编程之synchronized同步锁锁的是谁
切记,使用synchronized同步锁,锁的是对象,不是类。
以下代码是一个错误例子:
/**
* @Author: StupidZhe
* @Date: Created in 2017/11/25
* @Description: 使用synchronized关键词来锁定对象
*/
public class SyncTest implements Runnable {
private static int a;
public void print() {
System.out.println(++a);
}
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
executor.execute(new Thread(new SyncTest()));
}
executor.shutdown();
}
@Override
public void run() {
synchronized (this) {
while (a < 100) {
try {
Thread.sleep(500);
print();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
// 挑选了局部输出
-------output---------
37
37
39
40
41
41
41
42
43
44
45
44
可以看出来同步锁似乎没有成功锁住这段代码。
其实上面的话有问题,同步锁锁住的不是代码,而是对象。
听到这句话,大家是否意识到上述的代码的错误之处?问题就出在下面这段代码:
executor.execute(new Thread(new SyncTest()));
在每个线程中都是一个新的Runnable对象,这就导致实际上每个线程运行着不同的对象,而同步锁锁住的是对象,这就出现上述问题。
修改如下:
public static void main(String[] args) {
SyncTest syncTest = new SyncTest();
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
executor.execute(new Thread(syncTest));
}
executor.shutdown();
}
使用一个对象,就不会出现上述同步锁没锁住的问题。