Java中的synchronized关键字原理详解

深入解析Java中的synchronized关键字 接下来是偏向锁,我们还是用同样的代码即可,需要注意的是偏向锁必须在jvm启动后的一段时间才会运行,所以如果我们想打印偏向锁必须让线程休眠那么几秒,这里笔者就偷懒了一下,通过设置jvm参数。打印结果如下,我们只需关注第一行的object header,可以看到第一列的00000001,我们看到后3位为001,偏向锁标记为0,锁标记为01,001这就是我们说的无锁状态。上文讲解锁升级的之后,我们一直在说对象头的概念,所以为了能够直观的看到锁对象中对象头锁标记和锁状态的变化,我们这里引入一个jol工具。 阅读详情

Java中的synchronized关键字原理详解

在Java多线程编程中,保证线程安全是十分重要的问题。而synchronized关键字,是Java中最常用的同步机制之一。本文将深入学习synchronized关键字的原理,包括为什么能够保证线程安全、如何保证或实现原子性、可见性和有序性等内容。

什么是synchronized?

synchronized是Java中最基本的同步机制之一,用来保护共享资源的访问。它可以修饰方法或代码块,被修饰的方法或代码块被称为同步方法或同步块。当一个线程想要执行同步方法或同步块时,它必须先获取该方法或块的锁,如果其他线程已经持有该锁,那么当前线程就会进入阻塞状态,直到其他线程释放了它所持有的锁。

synchronized关键字保证线程安全的原理

在Java中,线程安全是通过避免数据竞争(data race)来保证的。当多个线程并发地访问共享变量时,如果没有使用同步机制来保护这些变量的访问,就会出现数据竞争。也就是说,数据竞争的发生是因为多个线程在没有协调的情况下同时修改了同一个共享变量,从而导致该变量的值不确定或出现错误。synchronized关键字通过锁机制来保护共享对象的访问,从而避免数据竞争。

synchronized关键字的本质是对一个对象的监视器(monitor)进行访问控制。每个Java对象都有一个与之关联的监视器,当且仅当一个线程持有该对象的锁时,它才能进入这个对象的监视器中。在同步块中,首先需要获取锁,然后才能执行其中的代码,执行完毕后才会释放锁。在这个过程中,如果其他线程想要进入同步块,则必须等待当前线程执行完毕并释放锁之后才能继续执行。

synchronized保证原子性的实现

原子性是指一个操作或一组操作是不可分割的单位,要么全部完成,要么全部不完成。在多线程并发执行的情况下,如果没有采取特殊的措施,就会出现多个线程同时修改同一个变量,导致最终结果与预期不符。synchronized关键字可以用来保证特定代码块或方法的原子性。

假设有一个计数器,多个线程并发地对其进行自增操作:

public class Counter {
    private int count = 0;
    
    public void increment() {
        count++;
    }
}

该代码不是线程安全的,因为多个线程可能同时对count进行自增操作,从而导致计数器的值错误。可以使用synchronized关键字将increment()方法变成同步方法,从而保证其原子性:

public class Counter {
    private int count = 0;
    
    public synchronized void increment() {
        count++;
    }
}

以上代码中,increment()方法前加了synchronized关键字,表示该方法是同步方法,同一时刻只有一个线程能够调用该方法。这样就能够保证自增操作是原子性的,避免了数据竞争。

synchronized保证可见性的实现

可见性是指当一个线程修改了共享变量的值后,其他线程能够立即看到修改之后的值。如果共享变量没有被同步保护,那么其他线程就可能无法及时地看到共享变量的最新值,从而导致程序出错。synchronized关键字可以用来保证共享变量的可见性。

假设有两个线程A和B并发地对一个共享变量flag进行读写操作:

public class VisibilityDemo {
    private static boolean flag = false;
    
    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            while (!flag) {
                // do nothing
            }
            System.out.println("Thread A is finished.");
        }).start();
        
        Thread.sleep(1000); // 等待1秒钟,确保Thread A已经启动
        
        new Thread(() -> {
            flag = true;
        }).start();
    }
}

以上代码中,线程A不断地读取flag变量的值,直到其变为true才会结束。而在主线程中,等待了1秒钟之后就启动了另一个线程B,该线程将flag变量的值修改为true。根据线程安全的要求,应该能够看到线程A输出"Thread A is finished.",但实际上程序很可能陷入死循环,因为线程A无法及时地看到flag变量的最新值。

为了解决这个问题,可以使用synchronized关键字来保证变量的可见性。将flag变量声明为volatile类型即可保证共享变量的可见性:

public class VisibilityDemo {
    private static volatile boolean flag = false;
    
    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            while (!flag) {
                // do nothing
            }
            System.out.println("Thread A is finished.");
        }).start();
        
        Thread.sleep(1000); // 等待1秒钟,确保Thread A已经启动
        
        new Thread(() -> {
            flag = true;
        }).start();
    }
}

以上代码中,flag变量前加上了volatile关键字,表示该变量是一个共享变量,需要保证其可见性。这样一来,对flag变量的修改操作就会立即被其他线程看到,从而避免了可见性问题。

synchronized保证有序性的实现

有序性是指程序执行的顺序按照代码的先后顺序执行,在多线程并发执行的情况下需要特殊注意。在执行语句的过程中,可能会因为编译器或者硬件优化的原因导致指令执行顺序的改变,从而导致程序的执行结果出现错误。synchronized关键字可以用来保证程序的有序性。

假设有一个简单的例子,其中一个线程负责向共享的队列中添加元素,另外一个线程负责读取队列中的元素:

public class OrderDemo {
    private List<String> queue = new ArrayList<>();
    
    public synchronized void add(String element) {
        queue.add(element);
    }
    
    public synchronized String remove() {
        if (queue.isEmpty()) {
            return null;
        }
        return queue.remove(0);
    }
}

以上代码中,add()方法和remove()方法都被声明为同步方法,这样就能够保证它们的访问顺序是按照代码的先后顺序执行。

总结

本文主要介绍了Java中synchronized关键字的工作原理,包括如何保证线程安全、如何保证或实现原子性、可见性和有序性等内容。在多线程编程中,使用synchronized关键字是十分常见的方式,它能够保证程序的正确性以及保护共享资源的访问。需要注意的是,虽然synchronized关键字是保证线程安全的一种方式,但是它会降低程序的执行效率,因此在实际开发中应该根据实际情况进行选择。

Java synchronized(详细) 在Java中,`synchronized`关键字用于解决多线程并发访问共享资源时可能出现的线程安全问题。 阅读详情

相关推荐

Java Synchronized关键字原理

https://blog.youkuaiyun.com/tongdanping/article/details/79647337 总结及补充几点 首先要明确Synchronized锁定的是对象,即使当我们锁定的是方法时,锁定的依然是这个方法所在类的对象或类,锁信息放在Java对象头的MarkWord里。 从字节码层面理解Synchronized原理 当Synchronized修饰的是类的时是由于monitorenter和monitorexit指令. 当Synchronized修饰的是方法时是ACC_SYNCHRONIZ

诺浅的专栏 684

Java同步synchronized

一. synchronized是什么? synchronized是Java的一个关键字,synchronized依赖于JVM具体实现。 synchronized的作用 synchronized也称为同步锁。synchronized是一种独占锁。 synchronized的两大功能: 内存可见性 操作原子性 什么是内存可见性? 可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。 可参考《Java内存分级和指令重排序》。volatile也可实现内存

joedan0104的专栏 5904

深入理解Java中synchronized关键字的实现原理

9.synchronized的底层实现原理 (1)对象大小的计算 a. 在32位系统下,存放Class指针的空间大小是4字节,MarkWord是4字节,对象头为8字节。 b. 在64位系统下,存放Class指针的空间大小是8字节,MarkWord是8字节,对象头为16字节。 c. 64位开启指针压缩的情况下,存放Class指针的空间大小是4字节,MarkWord是8字节,对象头为12字节。 数组长...

夏日清风 1833

Java多线程(二)——synchronized 详解

java多线程

m0_45198397的博客 5334

PID温控实验平台搭建(二)——PID进阶知识介绍及源码分享

最近,我突发奇想去翻阅了一些我本科期间所做的一些小项目,发现都挺有意思的!希望通过我的讲解文章可以帮助你们少走一些弯路!今天,我要分享的是一个PID温控实验平台的搭建,这是一个系列文章,手把手地教你学习和认识PID算法,了解这种算法在温度控制中的应用。由于我知识有限,如果出现一些错误,希望大家可以帮助我指出来,我们一起学习进步!!!

qq_35953617的博客 8048

深入剖析QWEN 2.5模型架构:从GQA到RoPE的技术实现

本文深入解析了QWEN 2.5模型架构,重点介绍了其创新的GQA(分组查询注意力)和RoPE(旋转位置编码)技术实现。通过详细代码解读,展示了这些技术如何提升模型的计算效率和长文本处理能力,适用于代码生成和数学推理等任务。文章还提供了实践部署建议和调优经验,帮助开发者更好地应用这一先进模型。

weixin_42548816的博客 388

Java关键字之synchronized详解【Java多线程必备】

1. synchronized详解 2. synchronized使用注意事项和案例

Mr.绵羊的知识星球 6751

从DC到DCG:手把手教你搭建物理感知综合流程(含DEF文件处理避坑指南)

本文详细介绍了从Design Compiler(DC)过渡到DC Topographical(DCT)和DC Graphical(DCG)的完整操作框架,特别针对DEF文件处理提供避坑方案。通过环境准备、工具升级、DEF文件处理、DCG综合配置等步骤,帮助开发者高效应对28nm以下工艺节点的物理感知综合挑战,显著提升时序收敛效率。

weixin_27966471的博客 377

java 关键字 synchronized 的底层实现原理

特性描述关键字锁类型互斥锁(悲观锁)实现基础Java 对象头 + Monitor锁升级机制无锁 → 偏向锁 → 轻量级锁 → 重量级锁字节码支持优点使用简单,语义清晰,无需手动释放锁缺点性能较低(尤其在高竞争场景下),可扩展性差适用场景简单同步控制、兼容旧代码、对性能要求不极端的场景。

Java的专栏 1332

SU-03T1语音模组固件烧录与配置全指南

本文提供SU-03T1离线语音模组固件烧录与配置的完整指南。详细介绍了从硬件连接、软件环境搭建,到在智能公元平台定制唤醒词、命令词及引脚配置,最后使用专用工具完成固件烧录的全流程。重点解析了烧录过程中的关键步骤与常见问题解决方法,帮助开发者快速实现智能语音控制功能。

weixin_29159613的博客 467

【PINN物理信息网络】基于PINN物理信息网络求解泊松方程(python)

【PINN物理信息网络】基于PINN物理信息网络求解泊松方程(python)

k8291121的博客 2811

java synchronized关键字原理

synchronized关键字是jdk内置的同步锁,它是解决并发问题的一种最常用的方法。

千磨万击还坚韧,任尔东西南北风 698

特别章节-0.1 SolidWorks导出机械臂的URDF模型各个关节坐标系设置

通过Solidworks导出机械臂的URDF模型文件,建立机械臂的各个关节坐标系的规则以及注意点,详细步骤

六眼飞鱼的博客 1万+

synchronized关键字底层原理 Java

synchronized用法在我的另外一篇博客中有讲链接如下,这篇博客主要讲底层原理。 synchronized用法 预备知识 理解Java对象头与Monitor 在JVM中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充。 实例变量:存放类的属性数据信息,包括父类的属性信息,如果是数组的实例部分还包括数组的长度,这部分内存按4字节对齐。 填充数据:由于虚拟机要求对象起始地址必须...

qq_42411214的博客 243

ABAP 平台注册 OAuth 2.0 Client 的完整实践指南(覆盖 Authorization Code、SAML Bearer 与 PKCE)

本文详述了在ABAP平台上注册入站OAuth 2.0 Client的关键技术和操作要点。文章面向SAP技术人员,系统梳理了前置条件(TLS/SSL、技术用户、授权对象)、配置路径(SOAUTH2事务)、授权类型差异(授权码、SAML Bearer、PKCE)等重要内容。特别强调入站与出站配置的区别,并提供了保密客户端和公有客户端的配置指引。文中所有事务码和参数均参考SAP官方文档,包含多个实用案例和权限配置建议,为ABAP系统作为OAuth 2.0授权服务器的实施提供全面指导。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 297

4位无符号比较器设计

4位无符号比较器设计

好好学习,天天向上 7891

Java 中关键字锁 synchronized 核心原理

大家好,我叫马丁,是一名专业的 Java 程序员。我经常在 优快云 平台分享技术博客,希望能够帮助到大家。

持续分享有趣的技术干货 1210

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

java关键字底层原理,讲一下 synchronized 关键字的底层原理

synchronized 关键字底层原理属于 JVM 层面。① synchronized 同步语句块的情况public class SynchronizedDemo {public void method() {synchronized (this) {System.out.println("synchronized 代码块");}}}通过 JDK 自带的 javap 命令查看 Synchron...

weixin_32151313的博客 153

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Java中synchronized关键字的使用和原理

synchronized关键字的使用 synchronized 关键字是 Java 中一个独占式的悲观锁,可以用来修饰方法块和方法,根据锁定对象的类型进行分类,可以分为对象锁和类锁。 对象锁 修饰同步代码块:锁定对象为 this 或者实例对象; public class Sync{ private int a = 0; public void add(){ // 锁定对象为 this synchronized(this){

盛夏温暖流年 1260

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

(二)彻底理解Java并发编程之Synchronized关键字实现原理剖析

JVM启动后四秒内的普通对象,和四秒后的匿名偏向锁对象偏向锁状态:只有一个线程进入临界区轻量级锁状态:多个线程交替进入临界区重量级锁:多个线程同时进入临界区。

qq_66627105的博客 1762

java里面Synchronized关键字的底层原理

### Monitor对象 Monitor 对于每一个java对象都关联一个Monitor对象,如果使用synchronized关键,给对象上锁(重量级锁)之后,该对象的Mark word中就会设置指向Monitor对象的指针。下图是32位jvm的mark word 组成: 上图是Monitor的结构: 刚开始Monitor对象中的owner为null, 当线程Thread-2执行...

Rocky 726

java synchronized关键字用法和底层原理

摘要: synchronized是Java实现线程同步的关键字,通过监视器锁机制确保共享资源安全访问。它支持三种用法:同步实例方法(锁this)、同步静态方法(锁Class对象)和同步代码块(自定义锁对象)。配合wait()/notify()可实现线程协作,需注意必须在同步块内调用,并用循环防止虚假唤醒。底层通过对象头的Mark Word实现锁升级(无锁→偏向锁→轻量级锁→重量级锁),平衡性能与线程安全。关键点包括可重入性、锁范围最小化及与Lock的区别,重量级锁涉及系统调用开销较大。

zfj321的博客 1262

Java并发-Synchronized关键字实现原理

模拟并发叫号程序: public class TicketDemo extends Thread{ private static int index = 1; private static final int MAX = 50000; @Override public void run() { while(index<=MAX){ ...

liusCoding的博客 457

Java synchronized关键字详解:从入门到原理

摘要: Java的synchronized是内置同步机制,保证原子性、可见性和有序性。JDK 1.6后引入锁升级优化(偏向锁→轻量级锁→重量级锁),通过对象头Mark Word实现。现代JDK默认关闭偏向锁以减少开销。synchronized与ReentrantLock相比更简洁但功能较少,适用于普通同步场景。2026视角下,优先使用synchronized,高并发场景可考虑其他锁或无锁方案。其核心在于锁升级流程和内存语义,是经过深度优化的悲观锁。

likuolei的博客 561

java synchronized关键字在jvm中的实现原理

下

英俊帅比林的博客 770
上一篇: Java中的ReentrantLock实现原理
下一篇: Java中AQS的介绍及实现原理
JavaWizard-M
博客等级 码龄6年 3159粉丝 148原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值