Java中的锁与锁优化技术

这篇具有很好参考价值的文章主要介绍了Java中的锁与锁优化技术。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

自旋锁与自适应自旋

自旋锁是一种锁的实现机制,其核心思想是当一个线程尝试获取锁时,如果锁已经被其他线程持有,那么这个线程会在一个循环中不断地检查锁是否被释放,而不是进入睡眠状态。

自旋锁在JDK 1.4.2中就已经引入,只不过默认是关闭的,在JDK 6中就已经改为默认开启了。自旋等待本身虽然避免了线程切换的开销,但它是要占用处理器时间的,所以如果锁被占用的时间很短,自旋等待的效果就会非常好,反之如果锁被占用的时间很长,那么自旋的线程只会白白消耗处理器资源,而不会做任何有价值的工作,这就会带来性能的浪费。因此自旋等待的时间必须有一定的限度,如果自旋超过了限定的次数仍然没有成功获得锁,就应当使用传统的方式去挂起线程。自旋次数的默认值是十次。

在 JDK 6中对自旋锁的优化,引入了自适应的自旋。自适应意味着自旋的时间不再是固定的了,而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定的。如果在同一个锁对象上,自旋等待刚刚成功获得过锁,并且持有锁的线程正在运行中,那么虚拟机就会认为这次自旋也很有可能再次成功,进而允许自旋等待持续相对更长的时间,比如持续100次忙循环。另一方面,如果对于某个锁,自旋很少成功获得过锁,那在以后要获取这个锁时将有可能直接省略掉自旋过程,以避免浪费处理器资源。

锁消除

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

锁消除通常基于逃逸分析(Escape Analysis)。逃逸分析是一种确定对象的作用域和访问范围的技术。如果确定某个对象只能在一个线程内部访问,并且不会“逃逸”到其他线程,那么该对象上的同步操作是不必要的。

public String concatenate(String str1, String str2) {
    StringBuffer sb = new StringBuffer();
    sb.append(str1);
    sb.append(str2);
    return sb.toString();
}
   /* StringBuffer的append方法上面有synchronized,说明是同步代码块 */
	@Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }

在上面示例中,StringBuffer是线程安全的,其方法是同步的。但在concatenate方法中,sb对象只会被一个线程访问,不会逃逸到其他线程。通过逃逸分析和锁消除,JVM可以确定在这种情况下,sb上的同步操作是不必要的,并且可以安全地消除它们。

锁粗化

锁粗化是Java虚拟机为了优化锁操作而采取的一种技术。基本思想是将多个连续的加锁、解锁操作合并为一个大的锁块,以减少锁操作的开销。

synchronized (lock) {
    // code block 1
}
// other operations
synchronized (lock) {
    // code block 2
}

在上面代码中,两个连续的synchronized块可以被合并为如下一个大的synchronized块,从而减少锁的开销:

synchronized (lock) {
    // code block 1
    // other operations
    // code block 2
}

锁粗化可以减少锁操作的数量,降低锁的开销,从而提高程序的执行效率。同时,它还可以减少线程上下文切换和系统调用的次数,进一步提高系统的性能。

轻量级锁

轻量级锁能提升程序同步性能的依据是“对于绝大部分的锁,在整个同步周期内都是不存在竞争的”这一经验法则。轻量锁使用操作系统互斥量来实现,轻量级锁并不是用来代替重量级锁的,它设计的初衷是在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。 使用到了Mark Word

HotSpot虚拟机对象头Mark Word如下

Java中的锁与锁优化技术,JUC,java,jvm,开发语言,并发

轻量级锁的工作过程如下:

  1. 在代码即将进入同步块的时候,如果此同步对象没有被锁定(锁标志位为“01”状态),虚拟机首先将在当前线程的栈 帧中建立一个名为锁记录(Lock Record)的空间,用于存储锁对象目前的Mark Word的拷贝Java中的锁与锁优化技术,JUC,java,jvm,开发语言,并发
  2. 虚拟机将使用CAS操作尝试把对象的Mark Word更新为指向Lock Record的指针。如果这个更新动作成功了,即代表该线程拥有了这个对象的锁,并且对象Mark Word的锁标志位(Mark Word的 最后两个比特)将转变为“00”,表示此对象处于轻量级锁定状态。如果这个更新操作失败了,那就意味着至少存在一条线程与当前线程竞争获取该对象的锁,需要膨胀为重量级锁Java中的锁与锁优化技术,JUC,java,jvm,开发语言,并发
  3. 解锁过程也同样是通过CAS操作来进行的,如果对象的 Mark Word仍然指向线程的锁记录,那就用CAS操作把对象当前的Mark Word和线程中复制的Displaced Mark Word替换回来。假如能够成功替换,那整个同步过程就顺利完成了;如果替换失败,则说明有 其他线程尝试过获取该锁,就要在释放锁的同时,唤醒被挂起的线程。

偏向锁

偏向锁是Java为了进一步优化锁的性能而引入的一种锁机制。它是基于一个事实:在大多数情况下,锁不仅不会涉及多线程竞争,而且总是由同一线程多次获得。

假设当前虚拟机启用了偏向锁,那么当锁对象第一次被线程获取的时候,虚拟机将会把对象头中的标志位设置为“01”、把偏向模式设置为“1”,表示进入偏向模式。同时使用CAS操作把获取到这个锁的线程 的ID记录在对象的Mark Word之中。如果CAS操作成功,持有偏向锁的线程以后每次进入这个锁相关的同步块时,虚拟机都可以不再进行任何同步操作(例如加锁、解锁及对Mark Word的更新操作 等)。

一旦出现另外一个线程去尝试获取这个锁的情况,偏向模式就马上宣告结束。根据锁对象目前是否处于被锁定的状态决定是否撤销偏向(偏向模式设置为“0”),撤销后标志位恢复到未锁定(标志位 为“01”)或轻量级锁定(标志位为“00”)的状态,后续的同步操作就按照上面介绍的轻量级锁那样去执行。

Java中的锁与锁优化技术,JUC,java,jvm,开发语言,并发

需要注意的是,由于偏向锁不存储hash码,所以当对象的hash码被计算之后就无法进入偏向锁了

重量级锁

在Java的重量级锁机制中,对象头的Mark Word存储一个指向监视器(Monitor)的指针。监视器是一个重要的结构,它包括以下几个部分:

  1. 锁信息:包括锁的状态、拥有者和重入次数等。锁的状态表示锁是否被某个线程持有,锁的拥有者指出哪个线程当前持有锁,而重入次数表示锁被重入了多少次。

  2. 等待集:这是一个包含了所有正在等待某个条件成立的线程的集合。线程可以通过调用Object.wait()方法进入等待集,并通过Object.notify()Object.notifyAll()方法被唤醒。

  3. 入口集:这是一个包含了所有正在等待获取锁的线程的集合。当锁被释放时,这些线程会被唤醒,并尝试重新获取锁。

以下是重量级锁的操作过程以及Mark Word的变化:

  1. 锁的获取:当一个线程尝试获取重量级锁时,它会检查Mark Word中的指针以确定监视器的位置,并检查锁的状态。如果锁已经被其他线程持有,它会被放入监视器的入口集,并进入阻塞状态。

  2. 锁的释放:当锁的持有者线程执行完同步代码块并释放锁时,Mark Word中的锁信息会被更新,通常是重入次数的减少或锁状态的变更。同时,监视器的入口集中的线程会被检查,如果有线程在等待,它们会被唤醒并尝试重新获取锁。

  3. 锁的重入:如果一个线程已经持有锁,它可以重入同步代码块而无需重新获取锁。在这种情况下,监视器中的重入次数会增加。

  4. 等待和通知:线程可以通过调用Object.wait()进入监视器的等待集,并通过Object.notify()Object.notifyAll()被唤醒。在这种情况下,等待集和入口集中的线程状态会随着条件的变化而变化。

通过Mark Word中的监视器指针和监视器中的锁信息、等待集和入口集,重量级锁能够实现线程间的同步和通信,保证对共享资源的安全访问。文章来源地址https://www.toymoban.com/news/detail-727595.html

到了这里,关于Java中的锁与锁优化技术的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java编译器中的优化技术

              Java中的热点代码主要有两类,包括: 1、被多次调用的方法。 2、被多次执行的循环体。 前者很好理解,一个方法被调用得多了,方法体内代码执行的次数自然就多,它成为 “ 热点代 码 ” 是理所当然的。而后者则是为了解决当一个方法只被调用过一次或少量

    2024年02月15日
    浏览(30)
  • java高并发系列 - 第25天:掌握JUC中的阻塞队列

    这是java高并发系列第25篇文章。 环境:jdk1.8。 本文内容 掌握Queue、BlockingQueue接口中常用的方法 介绍6中阻塞队列,及相关场景示例 重点掌握4种常用的阻塞队列 Queue接口 队列是一种先进先出(FIFO)的数据结构,java中用Queue接口来表示队列。 Queue接口中定义了6个方法:

    2024年02月14日
    浏览(30)
  • jvm与锁

    今天是《面霸的自我修养》的第二弹,内容是Java并发编程中关于 Java内存模型(Java Memory Model)和锁的基础理论 相关的问题。这两块内容的八股文倒是不多,但是难度较大,接下来我们就一起一探究竟吧。 数据来源: 大部分来自于各机构(Java之父,Java继父,某灵,某泡,某

    2024年02月11日
    浏览(41)
  • Java开发 - 你不知道的JVM优化详解

    代码上的优化达到一定程度,再想提高系统的性能就很难了,这时候,优秀的程序猿往往会从JVM入手来进行系统的优化。但话说回来,JVM方面的优化也是比较危险的,如果单单从测试服务器来优化JVM是没有太大的意义的,不同的服务器即使环境相同,访问流量方面也是不一样

    2024年02月07日
    浏览(31)
  • Java技术整理(1)—— JVM篇

    1、什么是JVM? JVM是一个可运行Java代码的虚拟计算机,包括一套字节码指令集,一组寄存器,一个栈,一个垃圾回收,堆和一个存储方式栈。JVM 是运行在操作系统之上,并不与操作系统直接交互。 2、运行过程: 我们都知道Java源文件,通过编译器,能够产生相应的.class文件

    2024年02月14日
    浏览(28)
  • 什么是Java中的JVM(Java虚拟机)?

    JVM(Java虚拟机)是Java平台的核心组件之一,是一个用于执行Java字节码的虚拟计算机。Java源代码经过编译器编译,生成字节码文件(.class文件),然后由JVM来解释和执行这些字节码。JVM负责将字节码翻译成特定操作系统和硬件平台的机器码,从而实现跨平台的能力。   JVM具

    2024年02月15日
    浏览(36)
  • TOMCAT部署及优化(Tomcat配置文件参数优化,Java虚拟机(JVM)调优)

    TOMCAT tomcat :是一个开放源代码的web应用服务器,基于java代码开发的。也可以理解为tomacat就是处理动态请求和基于java代码的页面开发。可以在html当中写入java代码,tomcat可以解析html页面当中的java,执行动态请求,动态页面。 tomcat是机制存在一些问题,如果不对tomcat进行优化

    2024年02月13日
    浏览(21)
  • 深入探讨Java虚拟机(JVM)的工作原理与优化策略

    摘要:本文对Java虚拟机(JVM)的工作原理进行深入探讨,包括其内存管理、垃圾回收以及代码执行等方面。同时,文章还通过具体的代码示例,阐述了JVM的优化策略,旨在提高Java程序的性能。 Java虚拟机(JVM)是Java程序运行的基础平台,其重要性不言而喻。理解JVM的工作原

    2024年02月11日
    浏览(30)
  • JVM调优篇:探索Java性能优化的必备种子面试题

    首先面试官会询问你在进行JVM调优之前,是否了解JVM内存模型的基础知识。这是一个重要的入门问题。JVM内存模型主要包括程序计数器、堆、本地方法栈、Java栈和方法区(1.7之后更改为元空间,并直接使用系统内存)。 正常堆内存又分为年轻代和老年代。在Java虚拟机中,年

    2024年02月15日
    浏览(48)
  • JVM逃逸分析原理解析:优化Java程序性能和内存利用效率

    在Java开发中,性能和内存利用效率一直是开发者关注的焦点。为了提高Java程序的执行效率,JVM引入了逃逸分析技术。本文将详细解析JVM逃逸分析的原理,帮助读者深入理解其工作机制。 逃逸分析是一种用于确定对象在方法的生命周期内是否逃逸出方法外部范围的技术。在

    2024年01月20日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包