锁的状态分几种, 无锁状态--->偏向锁-->轻量级锁-->重量级锁
锁可以升级不能降级
目的是:提高获取锁和释放锁的效率.
注意:
线程获取锁,其实是在获取线程的monitior,加锁和解锁就是线程在执行monitorrenter和monitorexit方法
- 偏向锁
当一个线程获取锁的时候会在 锁中记录线程ID 这样在这个线程进入到这个锁中就不需要使用CAS操作进行加锁和解锁的操作了.
线程会先测试对象头中是否存储着执行当前线程的偏向锁,如果存在则尝试使用CAS算法将对象头中的偏向锁执行当前线程.
如果 当前线程在持有锁的时候,该锁被其他线程尝试获取, 其他线程获取锁失败时会发出撤销偏向锁的指令,当前线程接到命令后等待全局安全点时会暂停当前线程,将锁中的执行ID删除. 执行完撤销偏向锁后继续执行当前线程,但是当前线程已经不再持有当前锁,所以当前线程已经不是偏向锁状态.
1.1 关闭偏向锁
设置jvm参数: -XX:BiasedLockingStartupDelay=0
- 轻量级锁
加锁:
线程在获取锁之前jvm会在当前线程中的栈帧中创建用于存储锁记录的空间,线程获取锁时会尝试将对象头中的mark word 替换成为执行当前线程中指向锁记录的指针
解锁:
线程使用CAS操作将Mark Word(栈帧中的锁记录)替换到请求头中,如果成功代表没有竞争发生,如果不成功锁膨胀为重量级锁.
3.重量级锁:
因为轻量级锁会导致线程自旋会产生消耗,所以锁膨胀为轻量级锁的时候就不会进行降级了,如果对象头中的轻量级锁膨胀为重量级锁,所有获取锁的线程都会进行阻塞等待当前线程释放锁.
网友评论