轻量级锁

若第一个线程已经获取到了当前对象的锁,这时第二个线程又开始尝试争抢该对象的锁,由于该对象的锁已经被第一个线程获取到,因此它是偏向锁,而第二个线程在争抢时,会发现该对象头中的Mark Word已经是偏向锁,但里面存储的线程ID并不是自己(是第一个线程),那么它会进行CAS(Compare and Swap),从而获取到锁,这里面存在两种情况:
1. 获取锁成功:那么它会直接将Mark Word中的线程ID由第一个线程变成自己(偏向锁标记位保持不变),这样该对象依然会保持偏向锁的状态。
2. 获取锁失败:(自旋次数达到界限值)则表示这时可能会有多个线程同时在尝试争抢该对象的锁,那么这时偏向锁就会进行升级,升级轻量级锁。

轻量级锁主要有两种

  1. 自旋锁
  2. 自适应自旋锁

    自旋

    1. **自旋(Spin)**。其原理是:当发生对Monitor的争用时,若**Owner能够在很短的时间内释放掉锁**,则那些正在争用的线程就可以**稍微等待一下**(即所谓的自旋),自旋的时候将一直处于用户态,节省了切换状态的性能消耗。在Owner线程释放锁之后,争用线程可能会立刻获取到锁,从而避免了系统阻塞。不过,当Owner运行的时间超过了临界值后,争用线程自旋一段时间后依然无法获取到锁,这时争用线程则会停止自旋而进入到阻塞状态。所以总体的思想是:**先自旋,不成功再进行阻塞,尽量降低阻塞的可能性**,这对那些执行时间很短的代码块来说有极大的性能提升。显然,自旋在多处理器(多核心)上才有意义。<br />JVM对于自旋次数的选择,jdk1.5默认为10次,在1.6引入了**适应性自旋锁**,适应性自旋锁意味着自旋的时间不在是固定的了,而是由前一次在同一个锁上的自旋时间以及锁的拥有者的状态来决定,基本认为一个线程上下文切换的时间是最佳的一个时间。