jdk1.6对 synchronized进行了锁升级优化
1.6之前synchronized的锁效率比较低,原因是以下几点:
1、阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成,这种状态转换需要耗费处理器时间。
2、如果同步代码块中的内容过于简单,状态转换消耗的时间有可能比用户代码执行的时间还要长
3、线程阻塞(进队列) 上下文切换 操作系统的线程调度,这些都很影响性能
这种依赖于操作系统Mutex Lock所实现的锁我们称之为“重量级锁”,JDK 6中为了减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”。
无状态 -> 偏向锁 -> 轻量级锁 -> 重量级锁
1、无状态:就是没有加锁的状态
2、偏向锁:直接在当前对象加入线程ID
3、轻量级锁:如果有多个线程进来,CAS自旋加锁;不需要上下文切换唤起线程
4、重量级锁:线程达到一定数量后,将线程放入队列,由操作系统进行线程调度
轻量级锁不一定性能比重量级高,因为大量的CAS自旋空转,也会消耗CPU资源
不同锁在对象中的对应状态:
1、无锁 01
2、偏向锁 01
3、轻量级锁 00
4、重量级锁 10
PS:对象内部的组成结构:
1、对象头 markword 64bit 8个字节 = 8b
2、类型指针class pointer 指向元空间的class加载的地址32bit 4个字节 = 4b
3、length 数组长度 (只有集合才会有值)
4、instance data 实例数据
5、padding 填充 (满足对象大小是8个字节的倍数)
对象头信息如下(64位):