java中synchronized锁的升级过程

Java中的synchronized锁是一种用于实现线程同步的机制,它可以保证在多线程环境下的数据同步和共享资源的安全访问。在使用synchronized锁的时候,我们需要注意其锁的升级过程,因为锁升级过程直接影响着程序的性能和效率。

一、synchronized锁的升级过程

synchronized锁的升级过程可以分为三种状态,分别是无锁状态、偏向锁状态和重量级锁状态。下面详细讲解每种状态:

  1. 无锁状态

在未经过任何同步操作的情况下,对象处于无锁状态,此时线程是可以直接访问该对象的成员变量和成员方法的。

  1. 偏向锁状态

如果只有一个线程直接进行加锁和解锁操作,那么就会出现偏向锁状态。在偏向锁状态下,锁会记录下持有偏向锁的线程ID,以后该线程访问同步块的时候就可以直接使用偏向锁而不需要再次操作同步机制。如果有其他线程访问该同步块,则会撤销偏向锁,升级为轻量级锁。

  1. 重量级锁状态

如果存在多个线程争夺同一个对象并且使用synchronized关键字进行加锁操作,那么就会出现重量级锁状态。在重量级锁状态下,锁会使用操作系统的互斥量来完成同步机制。当一个线程获取锁时,其他线程必须等待获得锁的线程释放锁后才能再次去争夺锁。

二、synchronized锁的升级过程示例

为了更好地理解synchronized锁的升级过程,下面给出两个示例,分别是偏向锁和重量级锁状态的示例。

  1. 偏向锁状态示例
public class SynchronizedDemo {

    private static final int COUNT = 1_0000_0000;
    private static Lock lock=new ReentrantLock();
    private static int num = 0;

    public static void main(String[] args) throws InterruptedException {
        long start = System.currentTimeMillis();
        T1 t1 = new T1();

        lock.lock();
        while (--COUNT > 0) {
            num++;
        }
        lock.unlock();
        t1.start();
        t1.join();
        System.out.println("num:" + num);
        System.out.println(System.currentTimeMillis() - start);
    }

    private static class T1 extends Thread {

        @Override
        public void run() {
            lock.lock();
            num += 10;
            lock.unlock();
        }
    }
}

在这个示例中,主线程通过一个循环对变量num进行了多次累加操作,在执行完成后启动了一个子线程t1,t1线程的任务是对变量num进行加10操作。由于主线程对num进行了多次操作,因此这个场景无法完全满足偏向锁的条件,实际运行过程中也没有出现偏向锁状态,所有的操作都是重量级锁状态。

  1. 重量级锁状态
public class SynchronizedDemo {

    private static final int COUNT = 1_0000_0000;
    private static int num = 0;

    public static void main(String[] args) throws InterruptedException {
        long start = System.currentTimeMillis();
        T1 t1 = new T1();

        synchronized (SynchronizedDemo.class) {
            while (--COUNT > 0) {
                num++;
            }
        }
        t1.start();
        t1.join();
        System.out.println("num:" + num);
        System.out.println(System.currentTimeMillis() - start);
    }

    private static class T1 extends Thread {

        @Override
        public void run() {
            synchronized (SynchronizedDemo.class) {
                num += 10;
            }
        }
    }
}

在这个示例中,主线程对变量num进行多次累加操作的过程中使用了synchronized关键字,此时锁的状态为重量级锁,t1线程对num进行加10操作时,同样需要操作synchronized关键字,线程会被阻塞直到获得锁。

三、总结

如上述示例所示,在使用synchronized锁的过程中,应尽量减少线程之间对同一个对象的竞争,越少的竞争会带来更好的程序性能。同时,我们还需要注意synchronized锁的升级过程,尽量使线程的操作在偏向锁或者轻量级锁状态下完成,避免进入重量级锁状态,从而提高程序的效率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java中synchronized锁的升级过程 - Python技术站

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

相关文章

  • 使用json对象转化为key,value的对象数组

    将JSON对象转化为key-value的对象数组,我们可以使用JavaScript的map函数。 首先,我们需要将JSON字符串解析为JSON对象,使用JSON.parse()方法可以完成这一步操作。接下来,为了将JSON对象转化为key-value的对象数组,我们需要使用map函数,对JSON对象进行遍历,返回转化后的数组。 以下是完整的转化过程: 将JS…

    Java 2023年5月26日
    00
  • Java Apache Commons报错“TimeoutException”的原因与解决方法

    “TimeoutException”是Java的ApacheCommons类库中的一个异常,通常由以下原因之一引起: 网络连接超时:如果网络连接超时,则可能会出现此异常。例如,可能会尝试连接到不可用的主机或端口。 线程等待超时:如果线程等待超时,则可能会出现此异常。例如,可能会等待某个资源的可用性,但超时时间已过。 以下是两个实例: 例1 如果网络连接超时,…

    Java 2023年5月5日
    00
  • springboot2 生产部署注意事项及示例代码

    下面是对“Spring Boot 2 生产部署注意事项及示例代码”的详细讲解。 Spring Boot 2 生产部署注意事项 1. 外部配置 Spring Boot 2 推崇使用外部配置,在生产环境中,一般将配置分离成一个单独的配置文件,不要将配置硬编码在应用程序中。这样可以更方便地进行部署和管理,同时也减少 Hard Code 带来的维护成本。可以使用环境…

    Java 2023年5月15日
    00
  • java 将一个数组逆序输出的方法

    下面是Java将一个数组逆序输出的方法的攻略: 使用for循环,逆序遍历数组并输出 这种方法使用一个for循环来逆序遍历数组,并使用System.out.println()方法将数组元素逐一输出。代码如下: int[] arr = {1, 2, 3, 4, 5}; for (int i = arr.length – 1; i >= 0; i–) { …

    Java 2023年5月26日
    00
  • 使用SSM+Layui+Bootstrap实现汽车维保系统的示例代码

    下面就为大家介绍如何使用SSM+Layui+Bootstrap实现汽车维保系统的完整攻略。首先,我们将从环境搭建开始,分别介绍SSM框架、Layui和Bootstrap的使用方法和示例。 环境搭建 JDK 1.8及以上 Maven 3.X及以上 Tomcat 8.X及以上 Eclipse集成开发环境 以上环境安装配置完成后,我们就可以开始使用SSM+Layu…

    Java 2023年5月19日
    00
  • java中数组list map三者之间的互转介绍

    下面是“Java中数组List Map三者之间的互转介绍”的详细攻略。 一、数组与List集合之间的相互转换 1. 数组转List Array转List可以直接通过Arrays类中的asList方法实现,代码示例如下: String[] arr = new String[]{"a", "b", "c&quot…

    Java 2023年5月26日
    00
  • SpringMVC 整合SSM框架详解

    本文将介绍SpringMVC与SSM框架的整合。整个过程分为以下几步: 1.创建Maven项目: 首先需要创建Maven项目,可以选择maven-archetype-webapp创建一个Web项目,也可以选择其他适合的模板。 2.引入SpringMVC、MyBatis和其他依赖: 在pom.xml中加入依赖: <dependency> <g…

    Java 2023年5月16日
    00
  • Java多线程执行处理业务时间太久解决方法代码示例

    针对你提出的问题,我会给出一份详细讲解“Java多线程执行处理业务时间太久解决方法代码示例”的完整攻略,过程中会包含以下几个部分的内容: Java多线程执行处理业务时间太久的原因 解决Java多线程执行处理业务时间太久的解决方案 代码示例 为了更好的与你展开对话,接下来我会就每个部分分别进行详细说明。 Java多线程执行处理业务时间太久的原因 在Java多线…

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