【面试题】谈谈你对内存模型的理解可以吗?

本文探讨了Java内存模型中的主内存与工作内存概念,以及它们如何影响多线程并发操作。通过举例说明了`read/write`、`load/store`、`lock/unlock`等指令在并发`data++`操作中的作用,指出由于工作内存的存在可能导致数据不一致性和内存不可见性。同时,提到了`volatile`关键字在解决内存可见性上的局限性,强调了原子性问题的重要性。

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

8个指令:read/write、load/store、use、assign、lock/unlock

read

将主存中的数据读取到CPU的高速缓存cache中

write

将CPU的cache中数据写回到主存中

load

将CPU的高速缓存cache中数据加载到JVM的寄存器中

store

将JVM寄存器中的数据写入CPU的cache中

lock

对数据进行加锁操作

unlock

对数据进行解锁操作

assign

接收到赋值指令时,给工作内存中的变量赋值

use

数据被JVM进行运算操作

Java内存模型中有主内存、工作内存

对象放在堆内存中

主内存 线程对应自己的工作内存(CPU级别的缓存)

工作内存:寄存器、高速缓存、写缓冲区

public class HelloWord(){
	private int data = 0;
	public void increment(){
		data++;
	}
}

HelloWorld helloWorld = new HelloWorld();

//线程1
new Thread(){
	public void run(){
		helloWorld.increment();
		}
	}.start();

//线程2
new Thread(){
	public void run(){
		helloWorld.increment();
		}
	}.start();

上面这段代码在内存中的过程如下图所示

假设两个线程同时进行

(1)将data=0这个值从主内存中read出来

(2)将data=0这个值load到对应线程的工作内存中

(3)执行data++工作:从工作内存中将data=0值提出来,交给线程use执行data++操作

(4)线程执行完data++操作,将各自工作内存中的data值assgin设置为1

(5)将工作内存中的data=1store取出来

(6)尝试将data=1的值write写入主内存中

两个线程并发去更新data,可能会将data的值更新为1

【评论区】

1、java内存模型是对计算机的一个抽象,将整个计算过程分成了6步去执行。因为每个线程都对应一个工作内存,所以导致主存中的数据值可能并不是最新的,因此多线程情况下,data++的这个操作就会被覆盖掉。 为什么要有工作内存的?它带来了内存不可见性与伪共享这些问题。是因为CPU的速度远高于内存的读写速度,因此为了充分利用CPU资源,设计了对应的缓存,还有一些其他的加载机制。 避免内存不可见用volatile就行,但是volatile的语义并不能保证data++能达到预期效果,因为它没办法保证这个执行的原子性

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值