jvm八种原子性操作及synchronized锁机制

本文详细解析了Java内存模型中的8种原子操作,包括lock、read、load等,并介绍了synchronized锁机制的工作原理,确保线程的可见性和数据一致性。同时,文章也提及了volatile的缓存可见性实现原理。

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

Java内存模型--同步协议

关于主内存与工作内存之间的交互协议,即一个变量如何从主内存拷贝到工作内存。如何从工作内存同步到主内存中的实现细节。java内存模型定义了8种操作来完成,每一种都是原子操作:

  • lock(锁定):作用于主内存,它把一个变量标记为一条线程独占状态;

  • read(读取):作用于主内存,它把变量值从主内存传送到线程的工作内存中,以便随后的load动作使用;

  • load(载入):作用于工作内存,它把read操作的值放入工作内存中的变量副本中;

  • use(使用):作用于工作内存,它把工作内存中的值传递给执行引擎,每当虚拟机遇到一个需要使用这个变量的指令时候,将会执行这个动作;

  • assign(赋值):作用于工作内存,它把从执行引擎获取的值赋值给工作内存中的变量,每当虚拟机遇到一个给变量赋值的指令时候,执行该操作;

  • store(存储):作用于工作内存,它把工作内存中的一个变量传送给主内存中,以备随后的write操作使用;

  • write(写入):作用于主内存,它把store传送值放到主内存中的变量中。

  • unlock(解锁):作用于主内存,它将一个处于锁定状态的变量释放出来,释放后的变量才能够被其他线程锁定;

Java内存模型还规定了执行上述8种基本操作时必须满足如下规则:

(1)不允许read和load、store和write操作之一单独出现(即不允许一个变量从主存读取了但是工作内存不接受,或者从工作内存发起会写了但是主存不接受的情况),以上两个操作必须按顺序执行,但没有保证必须连续执行,也就是说,read与load之间、store与write之间是可插入其他指令的。

(2)不允许一个线程丢弃它的最近的assign操作,即变量在工作内存中改变了之后必须把该变化同步回主内存。

(3)不允许一个线程无原因地(没有发生过任何assign操作)把数据从线程的工作内存同步回主内存中。

(4)一个新的变量只能从主内存中“诞生”,不允许在工作内存中直接使用一个未被初始化(load或assign)的变量,换句话说就是对一个变量实施use和store操作之前,必须先执行过了assign和load操作。

(5)一个变量在同一个时刻只允许一条线程对其执行lock操作,但lock操作可以被同一个条线程重复执行多次,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁。

(6)如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新执行load或assign操作初始化变量的值。

(7)如果一个变量实现没有被lock操作锁定,则不允许对它执行unlock操作,也不允许去unlock一个被其他线程锁定的变量。

(8)对一个变量执行unlock操作之前,必须先把此变量同步回主内存(执行store和write操作)

 

synchronized

synchronized锁关键字实现原理

在线程执行到synchronized修饰的同步代码块之前,会把当前线程用的全部变量值从主内存read刷新到工作内存,

在同步代码块结束之前,会把变量值重新store刷新回主内存。

synchronized对于同一把锁,可以保证线程的可见性。

voliate缓存可见性实现原理:

底层实现主要是通过汇编lock前缀指令,它会锁定这块区域内的缓存(缓存行锁定)并会回写到主内存。

IA-32架构开发者对lock指令的解释:

1.会将当前处理器缓存行的数据立即写会系统主存

2.这个写回主内存的操作要通过总线,cpu总线嗅探机制监听到,会引起在其他cpu里缓存了该内存地址的数据无效(MES协议)

<think>好的,我现在需要回答用户关于JVM原子性、一致性和原子类的问题。首先,我需要确认自己对这几个概念的理解是否正确,然后再组织语言,用清晰的中文解释给用户。 首先,原子性。在并发编程中,原子性指的是一个操作不可中断,要么全部完成,要么都不做。比如i++这个操作,实际上包含读取、增加、写入三个步骤,如果没有同步措施,多线程下会导致问题。JVM如何保证原子性呢?常见的有synchronized关键字和Lock接口,它们通过锁机制确保同一时刻只有一个线程执行代码块。另外,原子类如AtomicInteger使用CAS(Compare and Swap)操作,底层由CPU指令支持,保证原子性。 接下来是一致性。这里可能指的是内存一致性或者程序执行结果的一致性。JVM的内存模型(JMM)定义了线程如何与主内存交互,通过happens-before规则确保可见性。比如volatile变量的写操作happens-before后续的读操作synchronized的解锁happens-before加锁。一致性需要原子性可见性和有序性的共同保障,避免出现脏读、幻读等问题。 然后是原子类,属于java.util.concurrent.atomic包下的类,比如AtomicInteger、AtomicLong等。它们利用CAS算法实现非阻塞的线程安全操作。CAS包含三个操作数:内存位置、预期原值和新值。如果内存位置的值等于预期原值,则更新为新值,否则不操作。这种机制相比锁机制,减少了线程阻塞,提高了并发性能。不过CAS可能存在ABA问题,可以通过AtomicStampedReference解决。 需要区分原子性和一致性之间的关系。原子性关注单个操作不可分割,而一致性关注多个操作的整体正确状态。比如转账操作,扣款和入账必须都成功或都失败,这需要原子性;而整个系统状态在操作前后保持一致,这是一致性。 在回答结构上,应该先分别解释原子性、一致性、原子类,再说明它们的联系和区别。可能需要举例说明,比如i++的问题,原子类如何解决,以及CAS的工作原理。同时,要指出原子类的优缺点,比如ABA问题和解决方法。 需要检查是否有遗漏的概念,比如JMM中的可见性和有序性是否应该提到。因为一致性涉及到这些方面,所以简要说明是有必要的。另外,用户可能对JVM底层如何实现这些机制感兴趣,比如内存屏障、CPU指令等,但需要保持回答不过于深入,保持易懂。 最后,确保使用正确的中文术语,结构清晰,分点说明,使用适当的例子帮助理解。避免使用Markdown格式,按照用户的要求用纯文本,数学公式用$...$和$$...$$。不过用户的问题中没有涉及数学公式,可能不需要使用,但要注意如果回答中有变量或代码,比如AtomicInteger,用代码块或者斜体表示?</think>### JVM原子性、一致性与原子类解析 #### 一、原子性(Atomicity) **定义**:原子性指一个操作不可被中断,要么全部执行成功,要么完全不执行。 **典型问题**:例如 `i++` 操作实际包含三步: 1. 读取当前值 2. 值加1 3. 写回新值 若多线程同时执行,可能导致结果错误。 **JVM保障方式**: 1. **锁机制**(如 `synchronized`、`ReentrantLock`):确保同一时刻仅一个线程访问资源。 ```java synchronized (lock) { i++; } ``` 2. **原子类**(如 `AtomicInteger`):基于CAS(Compare and Swap)实现无锁线程安全。 ```java AtomicInteger atomicInt = new AtomicInteger(0); atomicInt.incrementAndGet(); // 原子性自增 ``` --- #### 二、一致性(Consistency) **定义**:一致性指多线程操作后,系统状态符合预期逻辑,遵循业务规则(如转账总额不变)。 **依赖条件**: 1. **原子性**:操作完整执行。 2. **可见性**:线程修改后其他线程立即可见。 3. **有序性**:代码执行顺序符合预期。 **JVM保障方式**: - **Happens-Before规则**: - 单线程规则:同一线程内操作按顺序生效。 - `volatile`变量:写操作先于读操作。 - 锁释放:解锁先于后续加锁。 --- #### 三、原子类(Atomic Classes) **原理**:基于CAS(Compare and Swap)实现非阻塞同步。 **CAS流程**: 1. 读取内存当前值$V$。 2. 计算新值$N$。 3. 若内存值仍为$V$,则更新为$N$;否则重试或放弃。 **常用类**: - `AtomicInteger`、`AtomicLong`:数值原子操作。 - `AtomicReference`:对象引用原子更新。 - `AtomicStampedReference`:解决CAS的ABA问题(通过版本号)。 **优势**: - 无锁设计,减少线程阻塞,提升并发性能。 **缺点**: - **ABA问题**:值从$A→B→A$,CAS误认为未变化。 - **解决方案**:使用`AtomicStampedReference`记录版本号。 --- #### 四、总结与联系 | 特性 | 关键点 | 实现方式 | |------------|-----------------------------------|--------------------------| | **原子性** | 操作不可分割 | 锁、CAS | | **一致性** | 系统状态正确性 | 原子性+可见性+有序性 | | **原子类** | 无锁线程安全 | CAS底层支持 | **示例场景**: - 无锁计数器:`AtomicInteger` 替代 `synchronized`,性能更高。 - 状态标记:`AtomicBoolean` 控制线程开关。 通过合理使用原子类和锁机制,可在JVM中高效实现线程安全与数据一致性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值