足球梦网站建设的基本思路,沧州做企业网站,中国建设银行网站宁波,wordpress弹出广告文章目录 1、背景2、Monitor、Java对象、线程如何关联起来的#xff1f;3、synchronized锁升级4、锁升级之无锁 关于synchronized同步#xff0c;能用无锁结构就不要用锁#xff1b;能锁块#xff0c;就不要锁整个方法#xff1b;能用对象锁#xff0c;就不要用类锁。 用… 文章目录 1、背景2、Monitor、Java对象、线程如何关联起来的3、synchronized锁升级4、锁升级之无锁 关于synchronized同步能用无锁结构就不要用锁能锁块就不要锁整个方法能用对象锁就不要用类锁。 用锁能够保证数据的安全性但性能下降。无锁性能提升但安全性下降如何平衡
1、背景
在Java早期版本synchronized是重量级锁效率低下因为监视器锁monitor依赖底层操作系统的Mutex Lock系统互斥量来实现。 Java5之前用户态和内核态之间的切换 用户态和内核态之间切换指的是
Java的线程是映射到操作系统的原生线程之上的Java的start方法底层是native start0方法因此阻塞和唤醒一个线程都需要操作系统介入去切换CPU的状态来完成内核态这种状态切换需要耗费处理器的时间如果同步代码块很简单那切换的时间可能比代码执行时间还长。
而用户态和内核态有各自专用的内存空间、专用的寄存器 ⇒ 因此用户态切换到内核态还需要传递很多变量和参数过去且内核也要去维护这些值。
鉴于以上Java6后引入轻量级锁和偏向锁别一下就捅到重量级锁。一句话为了尽量减少用户态和内核态的切换次数。
2、Monitor、Java对象、线程如何关联起来的
如果一个Java对象被某线程锁住则
该Java对象的Mark Word中的Lock word指向monitor的起始地址Monitor的__Owner字段会存放拥有这个对象锁的线程的 id 关于Monitor的复习【Monitor】
Monitor是在JVM底层实现的底层代码是c。本质是依赖于底层操作系统的Mutex Lock实现而Mutex Lock 的切换需要从用户态转换到内核态中因此状态转换需要耗费很多的处理器时间所以synchronized在Java中是一个重量级操作。
3、synchronized锁升级
synchronized锁升级主要依赖Mark Word中锁标志位和释放偏向锁标志位。 偏向锁MarkWord存储的是偏向的线程ID 轻量锁MarkWord存储的是指向线程栈中Lock Record的指针 重量锁MarkWord存储的是指向堆中的monitor对象的指针
4、锁升级之无锁
无锁即初始状态一个对象被实例化后如果还没有被任何线程竞争锁那它就是无锁状态001 用JOL展示下一个对象在无锁状态下其对象头是如何记录的。
Object object new Object();
//hashcode方法是native的调用了才会生成否则为0
System.out.println(10进制 object.hashCode());
System.out.println(16进制 Integer.toHexString(object.hashCode()));
System.out.println(2进制 Integer.toBinaryString(object.hashCode()));
System.out.println(ClassLayout.parseInstance(object).toPrintable());结果分析前25位是没使用的unUsed再往后31位是hashcode倒着看