首页 > 其他分享 >Sychronized的锁升级过程是怎样的

Sychronized的锁升级过程是怎样的

时间:2024-05-11 17:32:28浏览次数:16  
标签:Thread 自旋 升级 获取 线程 偏向 Sychronized 轻量级 怎样

`synchronized`关键字的锁升级过程是Java为了提高锁的性能,减少在无竞争或多线程轻度竞争情况下的开销而设计的一套机制。这一过程主要涉及以下四个阶段:

1. 无锁状态:当一个对象刚创建时,并没有锁与其关联,处于无锁状态。

2. 偏向锁(Biased Locking):
-初始化:当第一个线程访问同步代码块或方法时,JVM会将对象头的MarkWord设置为偏向锁,并记录这个线程的ID。
-偏向:如果后续的访问仍然是由这个线程发起的,无需进行同步操作,直接执行代码即可,因为锁已经偏向于这个线程
-撤销:如果有其他线程尝试访问这个同步块,偏向锁将被撤销,并进入轻量级锁状态。撤销时会有一定的开销,包括检查偏向锁标识、CAS操作尝试清除偏向锁等。

3.轻量级锁(Lightweight Locking):
-自旋:当有第二个线程尝试获取锁时,偏向锁被撤销,转换为轻量级锁。线程会在自己的栈帧中创建一个称为Lock Record的空间,用于存储锁的Mark Word的拷贝。
-CAS操作:然后通过CAS操作尝试将对象头的Mark Word替换为指向Lock Record的指针。如果成功,线程获得锁;失败,则说明存在竞争,线程将自旋一段时间,不断尝试CAS操作直到成功或达到自旋上限。
-自旋失败:如果自旋超过一定次数(自旋阈值)仍未获得锁,轻量级锁将升级为重量级锁。

4.重量级锁(Heavyweight Locking):
-监视器锁:当多个线程竞争激烈,轻量级锁无法有效处理时,锁升级为重量级锁。此时,JVM会调用操作系统的互斥量(mutex)来实现线程阻塞和唤醒,这会导致线程挂起和恢复,开销较大。
-阻塞与唤醒:未获取到锁的线程会被阻塞,进入等待队列,而持有锁的线程执行完毕后,会唤醒队列中的下一个等待线程。

public class Synchronized2Example {
    // 对象锁示例
public synchronized void method1() {
        System.out.println("Method 1 executing by " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000); // 模拟耗时操作,增加锁竞争的可能性
} catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    // 代码块锁示例,锁定的是object实例
private Object object = new Object();

    public void method2() {
        synchronized (object) { // 这里使用的是对象锁
System.out.println("Method 2 executing by " + Thread.currentThread().getName());
            try {
                Thread.sleep(2000); // 模拟耗时操作
} catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Synchronized2Example example = new Synchronized2Example();

        Thread t1 = new Thread(() -> example.method1(), "Thread-1");
        Thread t2 = new Thread(() -> example.method2(), "Thread-2");

        t1.start();
        t2.start();

    }
}

运行这段程序,可以看到两个线程分别尝试访问这两个同步方法或代码块。虽然这个示例并不能直观展示锁升级的过程,但它可以帮助理解synchronized如何保证线程间的同步。

 

​​​​​​​锁升级的整个过程是不可逆的,一旦升级到重量级锁,就不会再降级回轻量级锁或偏向锁。这种设计旨在根据竞争程度动态调整锁策略,以达到最佳性能平衡。

 

注:

下面是对各个锁的解释

1.偏向锁:在锁对象的对象头中记录一下当前获取到该锁的线程ID,该线程下次如果又来获取
该锁就可以直接获取到了,也就是支持锁重入


2.轻量级锁:由偏向锁升级而来,当一个线程获取到锁后,此时这把锁是偏向锁,此时如果有
第二个线程来竞争锁,偏向锁就会升级为轻量级锁,之所以叫轻量级锁,是为了和重量级锁区分开来,轻量级锁底层是通过自旋来实现的,并不会阻塞线程


3.如果自旋次数过多仍然没有获取到锁,则会升级为重量级锁,重量级锁会导致线程阻塞


4.自旋锁∶自旋锁就是线程在获取锁的过程中,不会去阻塞线程,也就无所谓唤醒线程,阻塞和唤醒这两个步骤都是需要操作系统去进行的,比较消耗时间,自旋锁是线程通过CAS获取预期的一个标记,如果没有获取到,则继续循环获取,如果获取到了则表示获取到了锁,这个过程线程一直在运行中,相对而言没有使用太多的操作系统资源,比较轻量。

标签:Thread,自旋,升级,获取,线程,偏向,Sychronized,轻量级,怎样
From: https://www.cnblogs.com/89564f/p/18186870

相关文章

  • Sychronized的锁升级过程是怎样的
    `synchronized`关键字的锁升级过程是Java为了提高锁的性能,减少在无竞争或多线程轻度竞争情况下的开销而设计的一套机制。这一过程主要涉及以下四个阶段:1.无锁状态:当一个对象刚创建时,并没有锁与其关联,处于无锁状态。2.偏向锁(BiasedLocking):-初始化:当第一个线程访问同步代码块......
  • nginx升级
    nginx升级新版本源码目录./configure--user=nginx\--group=nginx\--prefix=/usr/local/nginx\--with-http_ssl_module\--with-openssl=/usr/local/openssl-1.1.1o\--pid-path=/var/run/nginx.pidmake mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/`......
  • Apache RocketMQ ACL 2.0 全新升级
    引言RocketMQ作为一款流行的分布式消息中间件,被广泛应用于各种大型分布式系统和微服务中,承担着异步通信、系统解耦、削峰填谷和消息通知等重要的角色。随着技术的演进和业务规模的扩大,安全相关的挑战日益突出,消息系统的访问控制也变得尤为重要。然而,RocketMQ现有的ACL1.0......
  • 璞华科技中标苏州工业园区“科技发展公司运营管理系统”升级改造项目
    近日,璞华科技中标苏州工业园区科技发展有限公司“科技发展公司运营管理系统”升级改造项目。苏州工业园区科技发展有限公司成立于2000年,是苏州工业园区管委会直属国有企业,聚焦以人工智能为引领的数字经济产业创新集群,重点布局集成电路设计、智能网联、工业软件、ITBT、大数据等......
  • 高端制造业,该选择怎样的文件外发控制系统才真正安全?
    高端制造业的类型多样,包括航空航天、新能源汽车、工业机器人、工业母机、激光加工等多个重要产业链。高端制造业是衡量一个国家核心竞争力的重要标志,也是制造业发展的必然过程。中国要实现由工业大国迈向工业强国的战略转型,就需要大力发展全球领先的高端制造产业。高端制造业技......
  • 差分升级库+卫星定位+乘客流量测量仪
    1、mcu_bsdiff_upgrade-适用于嵌入式单片机的差分升级通用库mcu_bsdiff_upgrade是一款适用于嵌入式单片机的差分升级库,通用所有单片机,如stm32、华大、复旦微、瑞萨等。适合嵌入式的差分升级又叫增量升级,顾名思义就是通过差分算法将源版本与目标版本之间差异的部分提取出来制作......
  • 纹理是怎样显示在模型上的
    看完games101的第8和9章,就会很好理解这些内容。三维世界中的模型是由点组成三角形,进而组成复杂的模型。每个面都有不同的颜色(像素),可以用纹理来贴上去,最后在形成在屏幕上。立方体例子如何把2d的图片包到3d的模型上面?把3d物品展开成平面(展UV),和小时候做包装纸那样Blender零......
  • synchronized原理-字节码分析、对象内存结构、锁升级过程、Monitor
    本文分析的问题:synchronized字节码文件分析之monitorenter、monitorexit指令为什么任何一个Java对象都可以成为一把锁?对象的内存结构锁升级过程Monitor是什么、源码查看字节码分析synchronized的3种使用方式作用于实例方法,对对象加锁作用于静态方法,......
  • Nginx请求访问控制是怎样实现的
    首先来看下什么是漏桶算法和令牌桶算法Nginx并不直接实现漏桶算法或令牌桶算法,但这些算法在控制网络流量和请求速率方面非常有用。这些算法通常在网络编程、API服务、负载均衡等领域中使用,以确保系统的稳定性和性能。漏桶算法(LeakyBucket):*漏桶算法用于限制数据的传输速率。它......
  • 升级Artalk评论至V2-8-3-解决Error-请求响应404
    记录升级Artalk评论至V2.8.3,并解决ArtalkErrorError:请求响应404,无法获取评论列表数据朗读全文Yourbrowserdoesnotsupporttheaudioelement.有什么用升级Artalk评论至V2.8.3解决ArtalkErrorError:请求响应404,无法获取评论列表数据心路历程Artalk配置的SMT......