Java内存模型

一、上图

二、Java内存模型的设计目的

1.屏蔽掉不同硬件、操作系统之间的内存访问差异,实现Java程序在各种平台下达到一致的内存访问效果(Java口号:write once,run anywhere)

2.定义程序中线程共享区域(堆、方法区)的变量访问规则(存在线程竞争问题)

 

三、内存交互指令以及使用限制

8个交互指令:

1.主内存变量操作指令:lock、unlock、read、write

2.线程工作内存变量操作指令:load、use、assign、store

 

使用限制:

1.read指令与load指令结合使用,store指令与write指令结合使用。不允许变量从主内存read后工作内存不load,以及从工作内存发起store后主内存不write

2.执行引擎assign变量副本后需立即store,store之后需立即write到变量,因此assign->store->write可列为一组顺序指令,执行引擎use变量之前要求从工作内存load变量,load之前要求从主内存read变量到工作内存副本,因此read->load->use可列为一组顺序指令

3.lock与unlock指令必须成对出现,且同一时刻只允许一条线程对一个变量进行lock操作,该线程可lock多次该变量,需要对应次unlock。当变量被lock后,需要清空全部工作内存中此变量副本的值,当执行引擎下一次使用该变量时,需执行read->load->use指令;变量执行unlock指令之前,必须先把变量同步回主内存中,需执行assign->store->write指令。

 

volatile基于指令的操作规则
1.volatile修饰的变量被使用前必须从主内存刷新最新的值,保证能看见其他线程的修改。即read-load-use

2.volatile修饰的变量赋值后必须立刻同步回主内存,以保证其他线程能看到自己的修改。即assign-store-write

3.volatile修饰的变量禁止指令重排序优化

结合以上思考:为什么被volatile修饰的变量多线程写入时会不准确?

 

两个线程操作a变量,正常结果应该是a=2,但实际结果是a=1。由于a++操作不具备原子性,导致并发问题。

所谓的可见性是指,此时a=1了,对其他将对a变量操作的线程(变量a未进入执行引擎进行处理)来说,会实时读取到这个值。

 

posted on 2019-06-17 08:03  _only_deng  阅读(153)  评论(0编辑  收藏  举报

导航