锁存在的四种状态:无锁、偏向锁、轻量级锁、重量级锁-synchronized
1.偏向锁
- 原理:当一个线程访问同步锁的代码块时,在对象头中存储线程的ID。后续这个线程再进入和退出这段加了同步锁的代码块时,不需要在此加锁和释放锁。
- 获取偏向锁:
2.1:获取锁对象的MarkWord,判断是否处于可偏向状态
2.2:是可偏向状态,则通过cas操作,把当前线程的ID写入到Markword中
如果cas成功,获得了锁对象的偏向锁,接着执行同步代码块
如果cas失败,说明其他线程已经获得了偏向锁。说明当前锁存在竞争,需要撤销已获得偏向锁的线程,并且把他持有的锁升级为轻量级锁
在应用开发中,关闭偏向锁:通过JVM参数UseBiasedLocking设置开关偏向锁
2.自旋锁cas
- 原理:另一个线程竞争锁时,这个线程在原地等待。知道获取锁的线程释放锁之后,这个线程就可以马上获得锁
cas默认情况下自旋的次数是10次,可以通过PreBlockSpin修改
jdk1.6之后,引入了自适应自旋锁,自适应意味着自旋的次数不是固定不变的
- 获取锁