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和锁膨胀机制,从而提高代码的性能。

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

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

相关文章

  • JSP安全开发之XSS漏洞详解

    JSP安全开发之XSS漏洞详解 跨站脚本(Cross Site Scripting,简称 XSS)攻击是指攻击者往Web页面里插入恶意的Script代码,当用户浏览该页面时,嵌入其中Web里面的Script代码会被执行,从而达到攻击者的目的,如盗取用户的Cookie、登录信息等。 XSS攻击的类型 反射型XSS攻击 反射型 XSS 攻击是指攻击者要求用户点击…

    Java 2023年6月15日
    00
  • Spring MVC项目中log4J和AOP使用详解

    在Spring MVC项目中,log4j和AOP是两个非常常用的组件。log4j可以帮助我们记录应用程序的日志,方便我们进行调试和排错。AOP可以帮助我们实现面向切面编程,例如日志记录、事务管理等。下面是log4j和AOP在Spring MVC项目中的详细攻略: 1. log4j log4j是一个Java日志框架,可以帮助我们记录应用程序的日志。在Sprin…

    Java 2023年5月18日
    00
  • Spring boot 集成 Druid 数据源过程详解

    下面是详细讲解“Spring Boot 集成 Druid 数据源过程详解”的攻略,包含两条示例: 1. 简介 Druid 作为一个高效且能够监控 SQL 执行的JDBC 连接池,被广泛应用于Java Web 开发中。在 Spring Boot 项目中,集成 Druid 数据源也是一个常见的需求。本文将会给出一份关于如何在 Spring Boot 中集成 Dr…

    Java 2023年5月20日
    00
  • Java中文件的读写方法之IO流详解

    Java中文件的读写方法之IO流详解 什么是Java IO流 Java IO(Input/Output)流是一种用于处理输入输出的机制,它为我们提供了读取和写入数据的方法,可从不同来源读取数据,例如网络、文件等,也可以将数据写入到不同的位置,例如文件、网络等。Java IO流分为输入流和输出流,其中,输入流用于读取数据,输出流用于写入数据。 Java IO流…

    Java 2023年5月19日
    00
  • Java反射(Class类,Class对象获取)

    Java反射机制指程序可以在运行时(程序运行时而不是在编译期间),获取或修改该程序在运行状态下的某个类的各种属性,方法和构造方法。Java反射机制在框架的设计和实现中使用广泛。 在Java中,反射机制主要通过Class类和Class对象来实现。Class类表示类的一个实例,每个类都有一个Class实例。Class对象是在运行时从类载入的数据类型,它保存着与类…

    Java 2023年5月26日
    00
  • java-jsp springmvc-controller 传值到页面的方法

    下面是完整的攻略: Java JSP SpringMVC Controller传值到页面的方法 在Java Web开发中,SpringMVC是一种常用的框架。在开发过程中,我们经常需要在Controller中处理数据,然后将处理后的数据传递到页面中进行渲染。本文将介绍SpringMVC Controller传值到页面的几种方法。 1. Model和Model…

    Java 2023年6月15日
    00
  • 详解SpringMVC在IDEA中的第一个程序

    详解SpringMVC在IDEA中的第一个程序 SpringMVC是一种基于Java的Web框架,它可以帮助我们快速地开发Web应用程序。本文将详细介绍如何在IDEA中创建第一个SpringMVC程序,并提供两个示例说明。 步骤1:创建Maven项目 首先,我们需要在IDEA中创建一个Maven项目。在创建项目时,我们需要选择Web应用程序类型,并勾选Spr…

    Java 2023年5月17日
    00
  • SpringMVC+ZTree实现树形菜单权限配置的方法

    下面是完整攻略: 1. 准备工作 1.1 搭建SpringMVC项目 首先我们需要搭建一个SpringMVC项目,这里不做过多介绍,建议使用Maven进行管理。 1.2 引入ZTree插件 在搭建完SpringMVC项目后,在项目中引入ZTree插件。可以使用CDN的方式,也可以下载到本地引入。 1.3 数据库设计 在实现权限配置时,需要通过数据库保存树形菜…

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