1、什么是Synchronized?
Synchronized是java中的关键字,是一种同步锁。它修饰的对象有以下几种:(类, 方法, 代码块)
synchronized可以保证方法或代码块在运行时,同一时刻只有一个线程可以进入到临界区(互斥性)所以它也是排它锁,同时它还保证了共享变量的内存可见性。
在JDK1.6版本之前一直被称为''重量级锁'',但是在1.6之后进行了大量的优化. 主要包括为了减少获得锁和释放锁带来的性能消耗而引入的 偏向锁 和 轻量级锁 以及其它各种优化之后变得在某些情况下并不是那么重了.在线程冲突较少的情况下,可以获得和CAS类似的性能;而线程冲突严重的情况下,性能远高于CAS。
详细可以参考 http://t.csdn.cn/1h4x8
2、Synchronized的四种状态
这四种状态是在jdk1.6之后引入的,分别为:(无锁->偏向锁->轻量级锁->重量级锁 ) 这几个状态会随着竞争情况逐渐升级。
无锁
无锁的特点就是修改操作在循环内进行,线程会不断的尝试修改共享资源。如果没有冲突就修改成功并退出,否则就会继续循环尝试。也就是CAS(CAS是基于无锁机制实现的)。
偏向锁
偏向锁是指一段同步代码一直被一个线程所访问,那么该线程会自动获取锁,降低获取锁的代价。
偏向锁只有遇到其他线程尝试竞争偏向锁时,持有偏向锁的线程才会释放锁,线程不会主动释放偏向锁。
轻量级锁
是指当锁是偏向锁的时候,被另外的线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,从而提高性能。
若当前只有一个等待线程,则该线程通过自旋进行等待。但是当自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁升级为重量级锁。
重量级锁
在轻量级锁状态下,如果有第三个来访时,就会自动升级成重量级锁
锁的优缺点
锁 | 优点 | 缺点 | 实用场景 |
偏向锁 | 加锁和解锁不需要CAS操作,没有额外的性能消耗,和执行非同步方法相比仅存在纳秒级的差距 | 如果线程间存在锁竞争,会带来额外的锁撤销的消耗 | 适用于只有一个线程访问同步快的场景 |
轻量级锁 | 竞争的线程不会阻塞,提高了响应速度 | 如线程成始终得不到锁竞争的线程,使用自旋会消耗CPU性能 | 追求响应时间,同步快执行速度非常快 |
重量级锁 | 线程竞争不适用自旋,不会消耗CPU | 线程阻塞,响应时间缓慢,在多线程下,频繁的获取释放锁,会带来巨大的性能消耗 | 追求吞吐量,同步快执行速度较长 |
注意:锁之间的相互转换过程是不可逆的,也就是说只能由无锁-->偏向锁-->轻量级锁-->重量级锁
用通俗的大白话来讲(我的理解):
- 偏向锁适用于几乎没有并发的时候,虽然可以有多线程,但不是同一时刻,每个线程的存活时间都很短
- 轻量级锁可以快速知道锁什么时候释放,不需要让线程进入阻塞队列,提高效率,缺点是增加了cpu的损耗。所以轻量级锁中有个cpu自旋,极大消耗cpu。当并发特别高的时候,对cpu损耗极大,浪费时间。
- 当高并发的情况,竞争失败就放入阻塞队列,这样对cpu消耗极少,这样就升级成了重量级锁。也就是说,在高并发情况下,我们选择重量级锁