synchronized锁升级


JAVA 1.6 之后的改进

  • 可重入锁

upload successful

  • 偏向锁

共享资源首次被访问时,JVM会对该共享资源对象做一些设置,比如将对象头中是否偏向锁标志位置为1,对象头中的线程ID设置为当前线程ID(注意:这里是操作系统的线程ID),后续当前线程再次访问这个共享资源时,会根据偏向锁标识跟线程ID进行比对是否相同,比对成功则直接获取到锁,进入临界区域(就是被锁保护,线程间只能串行访问的代码),这也是synchronized锁的可重入功能。

  • 轻量级锁

当多个线程同时申请共享资源锁的访问时,这就产生了竞争,JVM会先尝试使用轻量级锁,以CAS方式来获取锁(一般就是自旋加锁,不阻塞线程采用循环等待的方式),成功则获取到锁,状态为轻量级锁,失败(达到一定的自旋次数还未成功)则锁升级到重量级锁。

  • 重量级锁

如果共享资源锁已经被某个线程持有,此时是偏向锁状态,未释放锁前,再有其他线程来竞争时,则会升级到重量级锁,另外轻量级锁状态多线程竞争锁时,也会升级到重量级锁,重量级锁由操作系统来实现,所以性能消耗相对较高。

这4种级别的锁,在获取时性能消耗:重量级锁 > 轻量级锁 > 偏向锁 > 无锁。

为什么偏向锁被废弃?

偏向锁是 HotSpot 虚拟机的一项优化技术,可以提升单线程对同步代码块的访问性能。受益于偏向锁的应用程序通常使用了早期的 Java 集合 API,例如 HashTable、Vector,在这些集合类中通过 synchronized 来控制同步,这样在单线程频繁访问时,通过偏向锁会减少同步开销。随着 JDK 的发展,出现了 ConcurrentHashMap 高性能的集合类,在集合类内部进行了许多性能优化,此时偏向锁带来的性能收益就不明显了。偏向锁仅仅在单线程访问同步代码块的场景中可以获得性能收益。如果存在多线程竞争,就需要撤销偏向锁 ,这个操作的性能开销是比较昂贵的。偏向锁的撤销需要等待进入到全局安全点(safe point),该状态下所有线程都是暂停的,此时去检查线程状态并进行偏向锁的撤销。

文章目录
  1. 1. 为什么偏向锁被废弃?
| 本站总访问量次 ,本文总阅读量