Java中的synchronized 优化方法之锁膨胀机制

Java中的synchronized 优化方法之锁膨胀机制

Java中的synchronized是一种线程安全的同步机制,能够保证多个线程访问同一个对象的方法或段代码时,只有一个线程执行,其他线程等待,直到执行完毕后才能继续执行。然而,synchronized也可能带来一些性能问题。因此,Java提出了一些优化方法,其中之一就是锁膨胀机制。

什么是锁膨胀机制?

当一个线程访问一个对象的同步方法时,Java虚拟机会给该线程分配一个轻量级锁(也称为偏向锁),随着竞争的增加,会升级为重量级锁(也称为互斥锁),锁的等级越高,进入和退出同步块时所需的开销就会越大,从而影响代码的性能。

为了避免轻量级锁的使用过于频繁,Java提出了锁膨胀机制。如果一个线程多次获得轻量级锁失败,Java虚拟机会将该锁升级为重量级锁。当然,反之也会发生,如果一个线程持有重量级锁,但在synchronized代码块完成前就退出了,Java虚拟机会将该锁降级为轻量级锁。这种锁升级或降级的过程就被称为锁膨胀机制。

示例说明

为了说明锁膨胀机制,我们可以考虑以下两个示例:

  1. 没有锁膨胀机制
public class MyThread extends Thread {
    private Integer i = 0;

    public synchronized void increment() {
        i++;
    }

    public void run() {
        for (int j = 0; j < 10000000; j++) {
            increment();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(t1.i + t2.i);
    }
}

在这个示例中,我们定义了一个MyThread类,其中有一个increment方法,用来自增i这个变量。同时,我们在increment方法前加上了synchronized关键字,保证了多个线程对i变量的访问不会冲突。然后我们创建了两个线程t1和t2,让它们分别调用increment方法进行递增,最后输出递增的结果。

这里我们发现,如果没有锁膨胀机制,两个线程间会频繁地切换轻量级锁和重量级锁,导致性能下降。如果我们运行上述代码,就会发现线程执行需要较长时间。

  1. 使用锁膨胀机制
public class MyThread extends Thread {
    private Integer i = 0;

    public void increment() {
        synchronized (this) {
            i++;
        }
    }

    public void run() {
        for (int j = 0; j < 10000000; j++) {
            increment();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(t1.i + t2.i);
    }
}

在这个示例中,我们对上一个示例进行改进,将synchronized从方法中移到了代码块中,并将锁的对象改为this。这样就可以避免轻量级锁和重量级锁之间的频繁转换,从而提高了性能。

如果我们运行上述代码,就会发现线程执行时间有了明显的缩短。

小结

Java中的synchronized是一种重要的线程同步机制,但如果使用不当,会带来性能问题。为了优化synchronized的性能,Java提出了锁膨胀机制,避免了轻量级锁和重量级锁之间频繁切换的情况。我们需要根据实际情况合理地使用synchronized和锁膨胀机制,从而提高代码的性能。

阅读剩余 48%

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中的synchronized 优化方法之锁膨胀机制 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • jquery实现联想词搜索框和搜索结果分页的示例

    首先,需要明确的是,jQuery 是一个 JavaScript 函数库,其目的是使JavaScript的使用更容易,简洁。使用 jQuery 可以帮助我们更快捷地编写出与原生 JavaScript 相同的功能。 要实现一个联想词搜索框和搜索结果分页,大致可以分为以下几个步骤: 1. 设计 UI 首先,我们需要设计一下我们的页面 UI,包括搜索框、搜索结果展示…

    Java 2023年6月15日
    00
  • spring boot入门开始你的第一个应用

    下面我将详细讲解“SpringBoot入门:开始你的第一个应用”的完整攻略。 1. 环境搭建 在开始之前,我们需要安装Java和IDE,推荐使用IntelliJ IDEA进行开发。然后,我们还需要安装SpringBoot。 2. 新建项目 我们可以选择创建一个Maven项目或者Gradle项目,这里我选择创建Maven项目。使用IDEA创建Maven项目需要…

    Java 2023年5月15日
    00
  • 如何配置Eclipse实现定制登录界面

    如何配置Eclipse实现定制登录界面 介绍 Eclipse是一种常见的集成开发环境(IDE),可以用于许多不同的编程语言。为了简化开发者经常使用的Eclipse的登录窗口实现安装一个第三方插件。这个插件可以实现自定义的登录界面,使其符合你所需的需求。在本文中,我们将讨论如何配置Eclipse实现定制化登录界面并提供两个示例。 步骤 步骤1: 安装插件 我们…

    Java 2023年5月20日
    00
  • spring boot教程之产生的背景及其优势

    Spring Boot教程之产生的背景及其优势 产生背景 在传统的Java Web开发过程中,我们需要编写大量的配置文件,比如web.xml、spring.xml等。而随着技术的不断发展,Java Web开发过程中出现了很多新的框架,比如Spring、Spring MVC、Hibernate等。但是这些框架的集成配置却比较麻烦,需要编写大量XML配置文件。因…

    Java 2023年5月15日
    00
  • 如何两步解决maven依赖导入失败的问题

    当我们使用Maven处理项目依赖时,有时会出现依赖导入失败的问题。这时我们可以进行如下两步操作解决: 第一步:清空本地仓库 有时本地仓库会存储有损坏或不完整的依赖。为了从远程仓库重新拉取完整可用的依赖,我们需要先清空本地仓库。清空命令如下: mvn dependency:purge-local-repository 运行此命令后Maven会将本地仓库完全清空…

    Java 2023年5月20日
    00
  • MyBatis中的JdbcType映射使用详解

    1. 什么是JdbcType映射 在MyBatis中,默认情况下,MyBatis会自动根据JavaBean属性的类型来映射到对应的JdbcType数据类型。但是在某些情况下,根据JavaBean属性的类型无法满足实际需求,这个时候你可以通过手动进行JdbcType映射。 2. 如何进行JdbcType映射 在MyBatis中可以通过两种方式进行JdbcTyp…

    Java 2023年5月19日
    00
  • 传统tomcat启动服务与springboot启动内置tomcat服务的区别(推荐)

    传统Tomcat启动服务与Spring Boot启动内置Tomcat服务的区别 在传统的Java Web应用程序中,我们通常使用Tomcat等Web容器来启动应用程序。而在Spring Boot应用程序中,我们可以使用内置的Tomcat来启动应用程序。以下是传统Tomcat启动服务与Spring Boot启动内置Tomcat服务的区别: 区别一:部署方式 在…

    Java 2023年5月15日
    00
  • Java 中EasyExcel的使用方式

    下面是Java中EasyExcel的使用方式的完整攻略: 1. 简介 EasyExcel是一款基于Java开发的、功能强大的Excel读写解决方案,使用起来方便快捷,支持读写Excel、CSV、HTML、JSON等文件格式,并且具有高性能,内存消耗低等优点,是目前比较流行的Excel读写工具之一。 2. 如何使用 2.1 引入依赖 在项目中引入EasyExc…

    Java 2023年6月2日
    00
合作推广
合作推广
分享本页
返回顶部