java中的锁:Synchronized的四种状态(无锁、偏向锁、轻量级锁、重量级锁)

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消耗极少,这样就升级成了重量级锁。也就是说,在高并发情况下,我们选择重量级锁

你可能感兴趣的:(java,开发语言)