Java并发之synchronized实现原理深入理解

Java并发之synchronized实现原理深入理解

概述

Java中,synchronized关键字是实现多线程同步的一种重要机制,可以让代码块以原子性、独占性执行。在并发编程中,对synchronized的理解非常重要。本文将深入讲解synchronized的实现原理,包括synchronized的底层实现、锁升级机制等方面。

synchronized的实现原理

Java语言规范通过“锁对象”的概念实现了synchronized关键字。在每个Java对象上都存在一个锁(也称为监视器),线程在执行synchronized块之前,必须先得到锁;在执行完synchronized块之后,会将锁释放。锁的实现通过JVM底层实现,具体步骤如下:

  1. 查找对象头:访问对象头(Object Header)中的Mark Word(标记字段)。
  2. 确定锁状态:根据Mark Word判断对象的锁状态。当对象锁处于初始状态时,表示锁是自由的;当对象被某一个线程锁定时,锁就处于"busy"状态,其他请求锁动作的线程则会被阻塞挂起等待
  3. 转换锁状态:如果当前线程没有获取到对象锁,则JVM需要让线程进入阻塞状态,等待抢占锁。如果当前线程获取到了锁,则JVM会将锁的状态改成“locked,并将请求锁的线程记为ownerThread”

锁升级机制

JVM采用的锁升级方式是轻量级锁 -> 重量级锁,这种方式被称为锁的膨胀,也称为锁的升级。锁的升级是为了在多并发场景下,保证线程安全,避免死锁,提高程序性能。具体步骤如下:

  1. 轻量级锁:首先,JVM会将对象的Mark Word复制到线程线程的栈帧中,自旋尝试去获取锁,如果最终自旋成功,则代表此段同步代码块是处于线程共享的,锁状态会转化为:locked,ownerThread记录的就是这个自旋成功的线程。
  2. 重量级锁:在自旋尝试获取锁失败的情况下,线程就会进入到重量级锁, 将该线程睡眠相应时间(该时间内不占据锁对象)。在‘睡眠后,该线程重新进入阻塞队列,争夺锁。

示例说明

下面通过两个代码示例来说明synchronized的使用及实现原理:

示例1

public synchronized void doSth() {
    for (int i = 0; i < 10; i++) {
        System.out.println("doSth");
        // 睡眠100毫秒,方便线程切换
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上述示例中,我们定义了一个方法doSth(),在方法级别上使用了synchronized关键字修饰该方法。这样的话,当线程执行doSth()方法的时候,会先尝试去获取this这个对象的锁,如果获取到了锁,则该线程会持有锁并执行方法体中的代码;否则,此时处于阻塞状态,等待其它线程释放锁,进而争夺锁。如果多个线程同时访问doSth()方法,会出现互斥现象,即同一时间只有一个线程可以执行doSth()方法。

示例2

public void doSth() {
    synchronized (this) {
        for (int i = 0; i < 10; i++) {
            System.out.println("doSth");
            // 睡眠100毫秒,方便线程切换
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

在上述示例中,我们使用synchronized关键字加锁的形式来修饰代码块,而不再是方法级别。synchronized (this)表示该代码块锁住的同步对象是当前对象,即this,这样该代码块的锁对象就是this,相比于在方法级别上加锁,可以更为细粒度地控制锁对象,避免其他的线程过度等待。当线程访问该代码块的时候,也是先去获取this对象的锁。相比于在方法上直接使用synchronized关键字,代码块的使用更为灵活,但是需要自己维护好锁的释放和锁的获取,避免死锁等问题的发生。

总结

本文对synchronized的底层实现原理、锁升级机制做了详细的介绍,并结合实例进行了说明。对于Java并发编程的理解以及代码实现具有一定的借鉴作用。在实际开发中,应该根据实际需求来选择锁的实现方式并细致地处理好锁的获取和释放,提高程序的健壮性和性能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java并发之synchronized实现原理深入理解 - Python技术站

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

相关文章

  • Java多线程编程中synchronized线程同步的教程

    针对Java多线程编程中synchronized线程同步的教程,我将提供如下攻略: 1. 什么是synchronized线程同步? 在Java中,多线程编程中的线程会因为多进程调度的因素而产生混乱,造成程序不可预期的后果。为了保证线程的执行顺序和互斥性,我们通常采用synchronized关键字对某一段代码进行加锁,只有当一个线程执行完这段被加锁的代码之后,…

    多线程 2023年5月17日
    00
  • Java并发编程之JUC并发核心AQS同步队列原理剖析

    针对“Java并发编程之JUC并发核心AQS同步队列原理剖析”的完整攻略,下面我将为您进行详细讲解,内容包含以下几个方面: JUC并发核心AQS AQS(AbstractQueuedSynchronizer)是JUC(JDK中对Java并发编程提供支持的工具包)并发编程的核心组件。AQS是一个用于构建锁和同步器的框架,利用AQS能够简单地构造出无锁、可重入、…

    多线程 2023年5月16日
    00
  • PHP 异步执行方法,模拟多线程的应用分析

    下面是关于“PHP 异步执行方法,模拟多线程的应用分析”的完整攻略: 什么是PHP异步执行? 在PHP脚本执行时,通常是按照顺序执行的,即一行一行顺序执行。这就意味着,在执行一个比较耗时的操作时,脚本会被阻塞,等待操作完成之后再继续执行下一行代码。这种方式叫做同步执行。 异步执行就是一种不阻塞当前线程的执行方式,在操作耗时完成之前,程序能够继续执行下一行代码…

    多线程 2023年5月17日
    00
  • Java多线程之并发编程的基石CAS机制详解

    Java多线程之并发编程的基石CAS机制详解 什么是CAS CAS,即Compare And Swap,中文翻译为比较并交换。是一种无锁算法,用于实现多线程同步。在CAS操作中包含三个操作数:内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在CA…

    多线程 2023年5月16日
    00
  • 详解超线程、多核、多处理器的区别

    详解超线程、多核、多处理器的区别 在讨论超线程、多核、多处理器之间的区别之前,我们需要了解计算机中的两个重要概念:线程和核心。 线程:计算机中执行任务的最小单位,是CPU执行指令和操作的基本单元。每个CPU核心可以同时执行多个线程。 核心:计算机的核心是处理器中的一个物理处理单元,它可用于执行任何指令并完成基本的算术或逻辑运算。 现在让我们深入了解超线程、多…

    多线程 2023年5月17日
    00
  • c#多线程编程基础

    C#多线程编程基础 简介 多线程编程是指在程序中同时使用多个线程来执行多个任务。在C#中,使用多线程可以提高程序的性能和响应时间,增强程序的并发能力,更好地利用硬件资源。 C#中实现多线程编程的方法主要包括以下两种: 继承Thread类并重写Run方法 创建ThreadStart委托并通过它启动线程 多线程编程需要注意以下几个方面: 线程安全问题 线程同步问…

    多线程 2023年5月17日
    00
  • 如何用PHP实现多线程编程

    创建多线程程序可以增加应用程序的效率,对于 PHP 程序员来说,也要掌握多线程编程技术。 实现 PHP 多线程编程的方式有很多,比如使用 pthreads 扩展、使用 pcntl 扩展、使用多进程(fork)等。下面我们举两个例子分别介绍使用 pthreads 扩展和多进程实现多线程编程的方法。 使用 pthreads 扩展 pthreads 扩展是一个多线…

    多线程 2023年5月17日
    00
  • php使用curl并发减少后端访问时间的方法分析

    PHP使用cURL并发技术实现优化后端访问时间 在高并发的web应用中,后端向多个不同的目标执行HTTP请求是很常见的,并发执行这些请求是可以显著提高应用性能的。cURL库是PHP中强大而常用的HTTP客户端库之一,本文将介绍如何使用cURL的并发技术来减少后端访问时间。 什么是cURL并发技术? cURL并发技术是一种将多个HTTP请求同时发送到后端,并在…

    多线程 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部