Synchronized锁
1.synchronized是可重入锁
同一线程可对同一对象锁多次,同样也要释放多次,如果锁没有全部释放会产生死锁
2.默认情况下出现异常锁会被释放
如果不想要锁被释放,可使用catch
让锁不被释放
3.Synchronize锁升级
JDK早期的锁是重量级的锁 ,
锁不能用包装类和字符串常量.
同时不能使用null
值作为锁对象,如果锁为null
会在释放锁时发生NPE.
synchronized(object){
......
}
偏向锁:当只有一个线程访问时,会将线程ID记录在object
的Markword
此时的锁为偏向锁,如果线程继续回来执行则省去申请锁的过程,直接执行,偏向第一个到锁的线程.
自旋锁:如果出现线程的争用,升级为自旋锁,等待使用锁的线程释放锁,不会进入阻塞队列(在用户态),会占用CPU
重量级锁:如果自旋到一定次数(默认10次)依然得不到锁,锁将会被升为重量级锁,去向操作系统(切换到内核态)请求获取锁,此时的自旋线程进入等待队列,不占用CPU
–> 锁只能进行升级不能进行降级(hotspot),降级可在JVM层面进行实现
4.各种锁的应用场景
- 加锁代码执行时间短并且线程数比较少,用自旋锁.(
Lock、Atomic类
因为线程过多会同时占用CPU进行自旋等待) - 执行时间长或者线程数量多用系统锁.(
Synchronized
)