首页 > 系统相关 >19 Java内存模型与线程_JVM层面的锁优化

19 Java内存模型与线程_JVM层面的锁优化

时间:2022-12-16 20:23:09浏览次数:66  
标签:同步 Java String 19 线程 JVM 自旋 append

目录

1 锁优化历史

  1. synchronized 从 JDK1.0到JDK1.5 ,效率低
  2. JDK1.5到JDK1.6,JVM团队对synchronized进行深度优化,加入了:适应性自旋、锁消除、锁膨胀、轻量级锁、偏向锁 等优化技术
  3. JDK1.5 开始,加入java.util.concurrent,提供API层面的轻量级锁应用

为什么优化synchronized?

互斥同步对性能最大的影响是阻塞的实现,挂起线程和恢复线程的操作都需要转入内核态中完成,这些操作给Java虚拟机的并发性能带来了很大的压力。

2 自旋锁与自适应自旋

2.1 关于自旋锁

自旋锁历史进程:首次出现在JDK1.4.2,但默认关闭(使用-XX:+UseSpinning参数开启),在JDK6开始默认开启。

自旋锁实现逻辑:如果锁被其它线程占有,那么本线程不放弃处理器的执行时间,并执行一个忙循环(自旋),直至得到锁。

自旋锁弊端:如果锁被占用的时间很长,那么自旋的线程只会白白消耗处理器资源,带来性能的浪费

自旋锁优化:

  1. 引入自旋次数:如果自旋超过了限定的次数仍然没有成功获得锁,就应当使用传统的方式去挂起线程。自旋次数的默认值是10次,可以启用参数-XX:PreBlockSpin来更改。(次数在JDK1.4.2已经实现)
  2. 引入了自适应自旋

2.1 自旋锁优化:自适应自旋

原来:所有线程的自旋时间统一的(PreBlockSpin配置值 * 单次自旋时间)
自适应自旋:自旋的时间不固定,JVM根据前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定。
自适应自旋情形:

例如1:线程A、B,锁L。A先通过自旋获取锁,那么JVM认为B也能通过自旋获取到锁,随即给B分配自旋时间,并且这个时间也是综合之前的自旋时间
例如2:锁L,线程A B C 通过自旋,都没有获取到锁,那么JVM会对后续的线程省略自旋过程,以免浪费处理器资源

3 锁消除

定义:指虚拟机即时编译器在运行时,对一些代码要求同步,但是对被检测到不可能存在共享数据竞争的锁进行消除

判断依据:源于逃逸分析的数据支持,如果判断到一段代码中,在堆上的所有数据都不会逃逸出去被其他线程访问到,那就可以把它们当作栈上数据对待,认为它们是线程私有的,同步加锁自然就无须再进行。

举例:

一段看起来没有同步的代码:

public String concatString(String s1, String s2, String s3) 
{ 
    return s1 + s2 + s3;
}

javac编译后,会变为以下同等代码:

public String concatString(String s1, String s2, String s3) { 
    StringBuffer sb = new StringBuffer();
    sb.append(s1); 
    sb.append(s2);
    sb.append(s3); 
    return sb.toString();
}
//append()方法有synchronize修饰

分析:
jvm观察变量sb,经过逃逸分析后会发现它的动态作用域被限制在concatString()方法内部。可以采用无锁操作。
在解释执行时这里仍然会加锁,但在即时编译之后,这段代码就会忽略所有的同步措施而直接执行。

锁消除总结:

JVM会进行逃逸分析,符合条件的,在编译为机器码时,会消除所有同步措施

4 锁粗化

定义:假如一串零碎的操作都对同一个对象加锁,JVM会把加锁同步的范围扩展(粗化)到整个操作序列的外部

举例:
例如上面concatString()方法,将锁扩展到第一个append()操作之前最后一个append()操作之后,这样只需加锁一次

5 轻量级锁

逻辑:无竞争的情况下使用CAS操作去消除同步使用的互斥量
轻量级锁提升性能的依据:“对于绝大部分的锁,在整个同步周期内都是不存在竞争的”这一经验法则
过程分析:后续补充

6 偏向锁

逻辑:在无竞争的情况下把整个同步都消除掉,连CAS操作都不去做
“偏”的理解:锁会偏向于第一个获得它的线程,如果在接下来的执行过程中,该锁一直没有被其他的线程获取,则持有偏向锁的线程将永远不需要再进行同步。

过程分析:后续补充

标签:同步,Java,String,19,线程,JVM,自旋,append
From: https://www.cnblogs.com/knowledgeispower/p/16988221.html

相关文章

  • 25_Java中的Lambda表达式
    Java中的Lambda表达式()代表此接口中的唯一方法,"->"指向一个语句块{},{}语句块中表示这个方法的重写一、函数式编程思想概述​ 在数学中,函数就是有输入量,......
  • 运用ogg实现oracle 10g到19c schema级别的同步
    文档课题:运用ogg实现oracle10g到19cschema级别的同步.源端:192.168.133.108数据库oracle10.2.0.464位,实例名:orcl目标端:192.168.133.109数据库oracle19.16.0.0......
  • k倍区间【第八届蓝桥杯省赛C++B组,第八届蓝桥杯省赛JAVAB组】
    k倍区间给定一个长度为\(N\)的数列,\(A1,A2,…AN\),如果其中一段连续的子序列\(Ai,Ai+1,…Aj\)之和是\(K\)的倍数,我们就称这个区间\([i,j]\)是\(K\)倍区间。你能......
  • java常用类库(API)
    该章节学习方法:不要背,只需要将具体方法的作用记下来,需要用的时候直接查文档API的使用和常用包的概述java.lang包,是java语言的核心包,包中的所有内容由java虚拟机自动导......
  • Java同步器简述
    一、概述在并发编程领域,有两大核心问题:一个是互斥,即同一时刻只允许一个线程访问共享资源;另一个是同步,即线程之间如何通信、协作。主要原因是,对于多线程实现实现并发,一直以......
  • 2019 Yinchuan K
    K.LargestCommonSubmatrix题链其实这类题就是非常典因为他给出的是一个不重复的矩阵那么我们B都会对应A有且仅有一个位置我们抽象其B->A为一个特定的向量题意就转......
  • JAVA结业测试题及答案
    JAVA结业试题二1下列哪些方法互为重载方法,哪些方法是覆盖方法。答案用号码标识:4分publicclassA{  ①publicstaticvoidmethod(Stringstr){};  ②protected int......
  • JAVA面试题-CORE JAVA部分
    JAVA面试题-COREJAVA部分                   --感谢SD0501班毕业学员李晓宾的提供,希望对面试学员和在校学员有所帮助。1. 在main(String[]args)方法内......
  • VS2019发布至远程IIS部署流程
    服务器部署传统的开发将项目发布至本地桌面之后,复制至站点目录或通过FTP上传站点目录,有点小麻烦,通过开发工具VS2019本身集成的功能,可以一步到发布到远程IIS站点。条件:V......
  • JavaScript中this关键字使用方法详解
       在面向对象编程语言中,对于this关键字我们是非常熟悉的。比如C++、C#和Java等都提供了这个关键字,虽然在开始学习的时候觉得比较难,但只要理解了,用起来是非常方便和意义......