使用场景
注意当我们对之前传统的 synchronized 锁优化的时候 要注意场景
什么样的场景 可以适合优化成什么样 它带着一点
特殊场景定制化的意味
你不要把它理解成 synchronized的完全进化版
轻量级锁适合的场景 : 虽然一个对象有多线程访问 但是多线程访问的时间是错开的(没有竞争)
在Java虚拟机中,对象的头部包含了一些额外的字段用于实现锁。轻量级锁的实现依赖于对象头部的标记位和指针。
当一个线程访问一个同步块时,如果该同步块未被锁定,虚拟机会将对象头部的标记位设置为“轻量级锁”状态,并将当前线程的Thread ID记录在对象头部的指针中。这个过程称为CAS(Compare and Swap)操作。这样,其他线程在访问该同步块时,发现对象处于轻量级锁状态时会自旋一段时间,等待获取锁。自旋期间,线程不会被挂起,而是通过循环不断检查是否可以获取锁。
如果自旋等待的线程成功获取到锁并完成操作,那么轻量级锁解锁就完成了。如果自旋等待的线程自旋一段时间后仍未获取到锁,那么轻量级锁就会膨胀为重量级锁。
锁膨胀(Lock Inflation)
是指将轻量级锁转换为重量级锁的过程。当一个线程无法在自旋等待中获取到锁时,虚拟机会将轻量级锁膨胀为重量级锁。膨胀为重量级锁的过程包括操作系统级的线程阻塞和唤醒,涉及到操作系统的上下文切换,这对性能会有一定的影响。膨胀为重量级锁是为了避免自旋等待时间过长,浪费CPU资源。
自旋锁
是一种线程同步的方式,它是一种忙等待的策略。当一个线程请求获取锁时,如果锁已经被其他线程占用,该线程不会立即阻塞挂起,而是在一个循环中不断地进行自旋(空转)等待,尝试获取锁。自旋锁适用于锁的持有时间非常短暂的情况,期望能够通过自旋等待来避免线程切换的开销。