关于synchronized,在java官方文档上有个很不错的介绍,这里简要小结下:
synchronized语义主要有两方面的含义:
- 确保同一时刻只有一个线程可以运行synchronized块中的内容;
- 实现了happens-before语义,即前面进程在synchronized中的修改对后面进程都是可见的(利用acquire和release语义实现,这是内存模型重要概念之一)
具体实现:(以synchronized non-static method为例)
对于每一个java对象都有一个内在锁(intrinsic lock),当一个线程访问一个被synchronized修饰方法时,该线程首先acquire该对象的intrinsic lock,然后在方法返回或者抛出异常的时候release该intrinsic lock,这样既保证了访问的唯一性,又保证了该线程的对数据的修改对其他线程都是可见的(happens-before)。
也就是说,一个线程访问一个对象的synchronized non-static method时,其他所有线程试图访问该对象的任何synchronized non-static method(当然也包括synchronized static method)都将被挂起,直到第一个线程访问结束。
而对于访问synchronized static method时,由于它并非由一个对象所拥有,所以会将与该类相关联的 Class Object 的实例进行加锁,因此此时所有其他打算对synchronized method进行访问的线程都将被挂起。
此外,synchronized还提供对部分代码片段进行同步操作,但需要指定其加锁的Object。
其他资料:
- 在知乎上有一个关于Object和Class这两个类的一个很有趣的问题
- 在javaworld中有关于在jvm如何实现synchronized的文章