【浅谈Java】主要针对Java开发技术知识的讲解。不会大而全详细讲解某一技术知识,只在短暂无事的时刻让你学习或温习Java知识体系中的一叶飘零。
「浅谈Java」三,关键字synchronized同步机制-基础篇
为什么要锁消除
前面说过在获取锁线程竞争中 锁的升级是不可逆的。但是没有线程需要执行同步逻辑时,锁会恢复到“无锁”状态。锁消除有别于它们。
锁消除(即同步消除)是Java虚拟机在JIT编译时,通过对运行上下文的扫描,去除不可能存在共享资源竞争的锁,通过锁消除,可以节省毫无意义的锁开销,以达到提升性能节约资源目的。
锁消除配置
锁消除的前提是java必须运行在JVM server模式,同时必须开启逃逸分析:
-server -XX:+DoEscapeAnalysis -XX:+EliminateLocks
其中+DoEscapeAnalysis表示开启逃逸分析,+EliminateLocks表示锁消除。
逃逸分析
逃逸分析是一种确定指针动态范围的静态分析,它可以分析在程序的哪些地方可以访问到指针。在 Java 虚拟机的即时编译语境下,逃逸分析将判断新建的对象是否逃逸。
即时编译器判断对象是否逃逸的依据:一是对象是否被存入堆中(静态字段或者堆中对象的实例字段),二是对象是否被传入未知代码中。
锁消除
如果能证明一个对象不会逃逸到方法或线程之外,即其它方法或线程无法通过任何途径访问到这个对象,则可以为这个变量进行一些高效的优化。
栈上分配、标量替换和锁消除,正是基于逃逸分析结果的优化手段。
正常情况资源的竞争才会使用同步,一个变量是方法内的私有变量,存放在栈内存中是不需要同步的。如果加了同步锁就是锁消除的用武之时。
那么问题来了,为什么会出现不需要同步加锁的代码强加同步逻辑呢?因为许多同步措施并不是程序员自己编码加入的,大部分都是隐式同步。如StringBuffer、Vector、HashTable等这些线程安全的类。使用它们的代码块JVM会通过逃逸分析判断其内部的加锁可否操作消除。
【浅谈Java】本篇为synchronized的后续,主要对上篇文章的补充说明。感谢阅读,求关注,求点赞。随手点赞,留有余香。学习是冰冻三尺非一日之寒,愿与诸君共勉励。