应用场景
<ol><li><font color="#31a8e0">修饰实例方法,进入同步代码前要获得当前实例的锁</font></li><li><font color="#31a8e0"> 修饰静态方法,进入同步代码前要获得当前类对象的锁</font></li><li><font color="#31a8e0"> 修饰代码块,进入同步代码前要获得指定对象的锁</font></li></ol>
cas
<font color="#31a8e0"><span style="font-size: inherit;">通过cas, 比较并交换</span><br>1: 如果当前的owner为空, 则将owner更新成当前线程<br> 2: 然后返回的值是上次owner的值, 如果为空, 就表示是重新给owner赋值了新的线程<br> 3: 如果返回的是当前的线程, 那么就表示正在进行重入操作, 计数器++</font>
<font color="#f15a23">两个结论, synchronized是通过cas得到锁的, 并且是可重入锁 </font>
锁优化(升级)
<font color="#31a8e0">0: 无锁, <br> 1: A线程进入同步代码块, cas修改对象头Mark Work<br> 2: 进入偏向锁, 这时, B线程也进入了同步代码块<br> 3: 发现已经被占用, 开始撤销偏向锁 (撤销就是在有两个线程, 其中有竞争关系发生的时候)<br> 4: 升级成轻量级锁, 轻量级锁中再存在竞争的锁<br> 5: 实现自适应自旋, 会根据你上一次成功的次数, 来设置<br> 自旋操作替代了原本的阻塞场景, 因为阻塞, 唤醒, 都涉及到用户态和内核态的切换的, 也是有性能问题<br> 长期自旋的话, 也不好, 长期占用时间片<br> 6: 如果自旋次数到了, 还没获取到锁, 那么锁膨胀<br> 7: 进入重量级锁 <br> 锁可以升级, 但是不能倒退, 在进入重量级锁后只有可能通过gc垃圾回收器处理成无锁</font>