锁升级
jdk1.6之前,是靠重量级锁,monitor它是基于操作系统层面的方法来实现互斥锁的,每次都需要切换到内核态,对性能会产生影响
进入synchronized后,会首先在线程栈中创建一个锁记录,它的object字段指向锁对象,并用CAS将锁记录的地址存储在对象头的mark word中
根据对象头中的记录,如果对象此时无锁,就获得轻量级锁
如果CAS修改失败,说明发生了竞争,会再去申请monitor,升级为重量级锁,原来持有锁的线程也会走重量级锁的解锁流程
如果当前线程已经持有该锁了,说明当前线程已经持有该锁了,会多加一条锁记录并把第一部分设置为null
自旋优化
适合多核cpu
由于进入entryList阻塞会导致上下文切换,所以线程竞争不到锁时,会先自旋重复尝试几次
偏向锁
锁重入的情况下,每次都会尝试CAS,对性能也会造成一定影响
jdk 1.6以后,引入了偏向锁,只有第一次使用CAS,将线程ID设置到锁对象的Mark Word头中(之前是用锁记录替换markword),这样就可以根据线程id判断是否是自己线程持有锁,不用CAS了