并发之java内存模型
java内存模型的规范
java内存模型规定了一个线程如何和何时可以看到其他线程的修改过后的共享变量的值,以及在必须时如何同步的共享变量.
如果两个对象同时调用同一个对象上的方法,他们将会都访问这个对象的成员变量,但是每个成员都拥有了这个对象的私有拷贝(左图).
CPU
从上图可以看出,在一个计算机有两个或者多个cpu的基础上同时运行多个线程是非常有可能的.
这意味着,如果你的java程序是多线程的,是完全可能并发执行的
cpu Registers
cpu寄存器,每个cpu都包含着一系列的寄存器,他们是cpu内存的基础,cpu寄存器上执行的速度比主存快,这是因为计算机对cpu寄存器的访问速度远大于主存
cpu Cache Memory
高级缓存,内存与处理器之间的缓冲,将运算所需要的数据复制到缓存中,让运算可以快速运行.
java内存模型抽象结构图
在这里,如果线程A和线程B要通信的话,必须要经历下面2个步骤:
- 线程A要把本地内存A中的共享变量放到主内存里面去
- 线程B到主内存中去读取已经更新过的共享变量
这样来说的话,因为A和B线程互相不可见,所以会产生这么一个错误
主内存 变量为1
线程 A 把 1 拿过来执行 +1操作,等于2,放回去
线程 B 同样把 1 拿过来执行 +1操作,等于2,放回去
因为B不会等A完事了再去操作,所以出错.所以我们就要加一下同步的手段.
同步的八种操作
- lock(锁定) : 作用域主内存的变量,把一个变量表示为一条线程独占状态,可以被一条线程执行多次.
- unlock(解锁) : 作用域主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定
- read(读取) : 作用域主内存的变量,把一个变量值充主内存专属到线程的工作内存中,一遍随后的load动作使用
- load(载入) : 作用域工作内存的变量,他把read操作从主内存中得到的变量值放入工作内存的变量副本中.
- use(使用) : 作用于工作内存的变量 ,把工作内存中的一个变量值传递给执行引擎
- assign(赋值) : 作用域工作内存的变量,他把一个从执行引擎结束到的值赋给工作内存的变量
- store(存储) : 作用域工作内存的变量,把工作内存中的一个变量的值传送到主内存中,以便随后的write的操作
- write(写入) : 作用域主内存的变量,他把store操作从工作内存中的一个变量的值传送到主内存的变量中