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---------373739404141414243444544
可以看出来同步锁似乎没有成功锁住这段代码。
其实上面的话有问题,同步锁锁住的不是代码,而是对象。
听到这句话,大家是否意识到上述的代码的错误之处?问题就出在下面这段代码:
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(); }
使用一个对象,就不会出现上述同步锁没锁住的问题。