Java synchronized的实现原理?

news/2025/2/3 15:04:45 标签: java, 开发语言

大家好,我是锋哥。今天分享关于【Java synchronized的实现原理?】面试题。希望对大家有帮助;

Java synchronized的实现原理?

1000道 互联网大厂Java工程师 精选面试题-Java资源分享网

Java 中的 synchronized 关键字用于实现同步控制,确保在多线程环境中对共享资源的访问是线程安全的。它的实现原理涉及到 对象监视器(monitor)锁(lock)JVM 的内部机制。下面详细解释 synchronized 的实现原理。

1. 对象监视器(Monitor)

在 Java 中,每个对象都关联着一个 监视器(monitor),它用于控制对该对象的访问。每个线程在执行一个同步代码块时,需要获得该对象的监视器。

  • 对于实例方法,监视器是当前对象 (this)。
  • 对于静态方法,监视器是该类的 Class 对象。

监视器是一种互斥锁,确保只有一个线程可以访问同步代码块或方法,其他线程必须等待直到当前线程释放监视器。

2. 获取和释放锁

  • 加锁:当一个线程进入同步代码块时,它会尝试获取该对象的监视器。如果没有其他线程持有锁,线程会成功获得锁,进入同步代码块或方法。
  • 释放锁:当线程执行完同步代码块后,它会释放锁,允许其他线程获取该锁。

如果有多个线程试图同时访问同一对象的同步方法或代码块,只有一个线程能够获得锁,其他线程会进入 阻塞状态,直到锁被释放。

3. JVM 中的实现细节

Java 中的 synchronized 锁机制是通过 JVM 的内存模型(JMM)对象头(Object Header) 实现的。

  • 对象头(Object Header):每个对象在内存中都有一个对象头,其中包括两个重要的信息:锁标志锁对象的引用。这些信息由 JVM 内部管理,用于同步控制。

    对象头结构:

    • Mark Word:包含锁相关信息,表示锁的状态。
    • 指向类的引用:指向该对象所属类的元数据。
  • 锁标志:在对象的 Mark Word 中,锁标志标识该对象是否已经被锁定,以及锁的类型和状态。锁的类型通常有:

    1. 无锁:没有线程持有锁。
    2. 偏向锁:仅有一个线程持有锁。适用于大部分线程访问的场景,JVM 会通过偏向锁来减少加锁和解锁的性能开销。
    3. 轻量级锁:在没有其他线程竞争的情况下,多个线程尝试使用锁时,会通过轻量级锁来提高效率。轻量级锁通过自旋来避免引起线程的上下文切换。
    4. 重量级锁:当有多个线程竞争时,轻量级锁无法解决竞争时,JVM 会将锁升级为重量级锁,进入操作系统的互斥锁机制,性能开销较大。

4. 锁的优化

JVM 在实现 synchronized 时还进行了许多优化,以提高并发性能:

  • 偏向锁:偏向锁的目的是优化没有竞争的情况下,线程获得锁的速度。偏向锁会让一个线程在首次获取锁时,偏向于该线程,这样该线程后续执行时就不需要再次竞争锁,从而提高性能。

  • 轻量级锁:当锁没有被其他线程占用时,JVM 会使用轻量级锁,它通过原子操作来检查和修改锁的状态,避免了阻塞和上下文切换。

  • 自旋锁:当多个线程竞争同一锁时,JVM 会通过自旋锁(即线程在获取不到锁时,等待一段时间再重试,而不是立即进入阻塞状态)来减少线程的上下文切换。

  • 重量级锁:当锁竞争激烈时,JVM 会将锁升级为重量级锁,这通常意味着线程会阻塞并进入内核状态。这是最耗性能的状态。

5. synchronized 的内存语义

synchronized 关键字不仅仅是实现线程同步,还具有一定的内存语义。通过 synchronized,Java 可以确保线程之间的可见性和顺序性:

  • 可见性:当一个线程修改了被 synchronized 保护的变量的值时,其他线程能够及时看到该变量的最新值。因为锁的释放和获取涉及到主内存的同步。

  • 有序性:通过 synchronized 保证了线程执行顺序。一个线程在执行同步代码时,它会先将当前线程的工作内存刷新到主内存,然后其他线程在获取锁时可以看到这个修改。

6. 代码示例

下面是一个使用 synchronized 的简单示例,展示了 synchronized 如何控制对共享资源的访问:

class Counter {
    private int count = 0;

    // 使用 synchronized 关键字确保线程安全
    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

public class SynchronizedExample {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();

        // 创建多个线程来增加计数器
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });

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

        // 等待线程执行完毕
        t1.join();
        t2.join();

        // 输出最终的计数结果
        System.out.println("Count: " + counter.getCount());
    }
}

在这个例子中,increment()getCount() 方法是同步的,确保了 count 的访问是线程安全的。

总结:

synchronized 关键字在 Java 中的实现依赖于 JVM 内部的对象监视器和锁机制,通过在对象的头部存储锁标志来控制对对象的并发访问。JVM 还对 synchronized 锁进行了一些优化,例如偏向锁、轻量级锁和重量级锁,以提高并发性能。synchronized 不仅保证了线程之间的互斥访问,还确保了内存的可见性和有序性。


http://www.niftyadmin.cn/n/5840886.html

相关文章

Java基础知识总结(三十九)--File类

将文件系统中的文件和文件夹封装成了对象。提供了更多的属性和行为可以对这些文件和文件夹进行操作。这些是流对象办不到的&#xff0c;因为流只操作数据。 File类常见方法&#xff1a; 1&#xff1a;创建。 boolean createNewFile()&#xff1a;在指定目录下创建文件&#x…

[paddle] 矩阵相关的指标

行列式 det 行列式定义参考 d e t ( A ) ∑ i 1 , i 2 , ⋯ , i n ( − 1 ) σ ( i 1 , ⋯ , i n ) a 1 , i 1 a 2 , i 2 , ⋯ , a n , i n det(A) \sum_{i_1,i_2,\cdots,i_n } (-1)^{\sigma(i_1,\cdots,i_n)} a_{1,i_1}a_{2,i_2},\cdots, a_{n,i_n} det(A)i1​,i2​,⋯,in​…

V103开发笔记1-20250113

2025-01-13 一、应用方向分析 应用项目&#xff1a; PCBFLY无人机项目&#xff08;包括飞控和手持遥控器&#xff09;&#xff1b; 分析移植项目&#xff0c;应用外设资源包括&#xff1a; GPIO, PWM,USART,GPIO模拟I2C/SPI, ADC,DMA,USB等&#xff1b; 二、移植项目的基本…

Q#使用教程

Q# 是一种用于量子计算的编程语言&#xff0c;主要用于编写量子算法。 1. 环境配置 安装vscode2017以上 QDK下载地址&#xff1a;Azure Quantum Development Kit (QDK) - Visual Studio Marketplace 将下载好的QDK作为拓展配置到vscode里面。 2.代码 import Microsoft.Qu…

【数据结构】_时间复杂度相关OJ(力扣版)

目录 1. 示例1&#xff1a;消失的数字 思路1&#xff1a;等差求和 思路2&#xff1a;异或运算 思路3&#xff1a;排序&#xff0b;二分查找 2. 示例2&#xff1a;轮转数组 思路1&#xff1a;逐次轮转 思路2&#xff1a;三段逆置&#xff08;经典解法&#xff09; 思路3…

基础数据类型之整形

int int是最基础的整形变量&#xff0c;存储的是2*10⁹之间的整数&#xff0c;占用4B的内存 short 和名字一样&#xff0c;更短的整形&#xff0c;可存储10⁴之间的整数&#xff0c;占用2B的内存 long long 和名字一样&#xff0c;更长的整形&#xff0c;可存储9*10⁸之间…

第二篇:多模态技术突破——DeepSeek如何重构AI的感知与认知边界

——从跨模态对齐到因果推理的工程化实践 在AI技术从单一模态向多模态跃迁的关键阶段&#xff0c;DeepSeek通过自研的多模态融合框架&#xff0c;在视觉-语言-语音的联合理解与生成领域实现系统性突破。本文将从技术实现层面&#xff0c;解构其跨模态表征学习、动态融合机制与…

系统URL整合系列视频二(界面原型)

视频 系统URL整合系列视频二&#xff08;界面原型&#xff09; 视频介绍 &#xff08;全国&#xff09;大型分布式系统Web资源URL整合需求界面原型讲解。当今社会各行各业对软件系统的web资源访问权限控制越来越严格&#xff0c;控制粒度也越来越细。安全级别提高的同时也增加…