java线程代码块同步的关键字_java并发编程之synchronized关键字

本文详细解析了Java中的synchronized关键字,包括其使用方法、实现原理以及monitorenter和monitorexit指令的作用。synchronized用于保证多线程环境下的数据同步,通过对象锁实现线程安全。在代码块和方法上使用时,会涉及到对象实例或类级别的锁。其内部实现依赖于Java对象头信息和Monitor对象,确保线程同步和资源的正确访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

synchronized

Java语言的关键字,用来保证多线程场景中的,同一时刻只能有一个进程访问本方法或代码块(通过加java内置的锁),保证并发场景下的共享资源的操作同步。

一,使用方法:

修饰普通方法和普通代码块时(非静态),是一个对象实例的方法和代码块加锁(需要注意的是,因为锁是针对对象的,如果该对象的类中有多个方法加了synchronized,那么这些方法将被正在访问的线程同时锁住,其他线程不能访问其他synchronized方法)。

修饰静态方法和静态代码块时,就是给一个类的所有对象对该方法/代码块的调用。

二,synchronized的实现原理:

2.1synchronized代码块的同步实现

是通过monitorenter 和 monitorexit 指令来完成的,如下代码所示,在加了synchronized关键字后,jvm会在编译后在同步的代码块前后分别加入monitorenter 和 monitorexit 。

public class TestSync {

public static void main(String[] args) {

synchronized (TestSync.class){

System.out.println("synchronize");

}

}

}

如下图所示,为对应的代码块字节码,前后加了monitorenter 和 monitorexit;

monitorenter 和 monitorexit

2.2而synchronized修饰方法则稍有区别:

如下所示:

public class TestSyncMethod {

public synchronized void method() {

System.out.println("Hello World!");

}

}

对应的指令码如下,说明方法是直接在方法写synchronized关键字的,但处理过程与代码块类似:

synchronized方法

三,monitorenter和monitorexit的实现:

那么,monitorenter和monitorexit到底如何实现让多个线程的同步的呢。

3.1 首先,需要再了解下之前科普过的关于java对象头的信息(以32位jvm为例):

如下图所示,对象新建出来之后,默认“无锁”状态,而使用“偏向锁”和“轻量级锁”后续章节中讨论,本文默认synchronized走的是“重量级锁”(java6之前的实现)。

java对象头信息,摘自

“重量级锁”这一行,指向的指针就是指向monitor对象(重量级锁)。

且如果对象被某个线程占有,锁标志更新为"10"。

3.2 Monitor对象的实现方式(HotSpot虚拟机源码ObjectMonitor.hpp文件):

ObjectMonitor() {

_count = 0; //重入次数

_object = NULL;//对应的对象

_owner = NULL;//持有者(某个持有该锁的线程)

_WaitSet = NULL; //等待队列(线程等待唤醒的队列)

_EntryList = NULL ; //同步队列(多个线程进入后尝试获取锁的队列)

.....//其他属性

}

3.3 执行过程

如下图所示,当多个线程进入monitorenter时,先进入_EntryList 同步队列,尝试获取锁,如果获取失败,则在同步队列等待占有锁的线程先释放锁,如果获取成功,则_owner值指向该线程。如果该线程再次进入monitorenter,则_count+1。如果该线程占有过程中,执行了wait方法,则线程进入_WaitSet,并释放_owner值,_count为0,由其他线程抢占该monitor对象。抢占到monitor的线程执行完同步代码后,执行monitorexit,则并释放_owner值,_count为0。

线程抢占锁的原理

后面,我们还将继续在“锁”这一章节中讲述java6之后对锁的优化。

感兴趣的小伙伴请关注本人公众号:暖爸的java家园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值