目录
锁一共有四种状态,无锁状态,偏向锁,轻量锁,重量锁
三锁对比
注意锁的状态不是固定的,他会跟这竞争的升级而升级,锁只可以可以升级,不能降级,过程不可逆。
偏量锁(可以配置为没有)
适用场景:适用于单个线程,
原理:当加锁时,直接在对象头和栈帧中的锁记录里储存偏向锁的ID。下次自己的线调用的时候,查看对象头锁存在的还是自己的ID就直调用。
过程:
其中线程二介入就是撤销锁的过程,线程二访问对象是否有自己的线程ID发现没有,暂停线程一,将对象头的I设为空(也就是撤销了偏向锁),恢复复线程(CAS比较替换是指,将对像上加上信号量,要是返回的信号量不大于 , 对象内的,就重新取值返回计算。直到版本大于对象的·版本号为止)
关闭偏向锁:
偏向锁在Java 6和Java 7里是默认启用的,但是它在应用程序启动几秒钟之后才激活,如有必要可以使用JVM参数来关闭延迟:-XX:BiasedLockingStartupDelay=0。如果你确定应用程序里所有的锁通常情况下处于竞争状态,可以通过JVM参数关闭偏向锁:-XX:-UseBiasedLocking=false,那么程序默认会进入轻量级锁状态。
轻量级锁-——自旋锁(适合线程少时)
这样的设计在线程较少时,处理速会非常快。线程较多,自旋过多,会有很多自旋是无用的的,会导致CPU处理变慢,降低效率。
过程图
重量级锁(适合高并发)
当一个上时 , 其他线程进入阻塞队列 , 当不上锁时,通知线程们进入就绪队列,谁抢到线程谁就执行,其中一个抢到后,其他的线程再次进入阻塞队列。
优点:这样节约了CPU,让cpu的执行大部分,其余的挂起,适合高并发
虽然是就绪队列和阻塞队列不是单纯的队列选择机制,有其他选择机制