Java内存模型个人理解
个人理解Java并发问题主要有两个:
- 线程间如何通信
- 变量如何共享
针对第一个问题,Java使用共享内存来进行线程间通信,因为这种方式速度最快.而对于后一个问题则是用锁.
为了解决以上的并发问题并且保障跨平台行,Java定义了自己的内存模型.内存模型描述了程序中各个变量之间的关系,以及操作系统将变量存储到内存以及从内存中取出变量这样的细节.此处的变量不包括局部变量与方法参数,后者是线程私有的,不会被共享.所以说JMM帮助屏蔽了操作系统底层的细节,保障了程序的正确性.
JMM规定,所有的变量都存储在主内存中,每条线程有自己的工作内存,工作内存中的内容是对主内存中内容的拷贝. 线程对变量的所有操作(读取/赋值)都必须在工作内存中进行,然后按需要同步到主内存中,如下图所示:
JMM(Java内存模型)保障两个依赖操作之间的顺序性,但是对于没有依赖关系的任务,处理器在执行的时候是乱序的(指令重排序)。并且JMM也没有保障顺序一致性。
即一个多线程的任务,在每个单线程中看起来都是有序的,但是处理器执行起来是无序的,所以要对资源进行锁定。
JMM定义的内存间的操作:
对于一个变量如何从主内存拷贝到工作内存、如何从工作内存同步到主内存之间的实现细节,Java内存模型定义了以下八种操作来完成
1.lock(锁定):作用于主内存的变量,把一个变量标识为一条线程独占状态。
2.unlock(解锁):作用于主内存变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。
3.read(读取):作用于主内存变量,把一个变量值从主内存传输到线程的工作内存中,以便随后的load动作使用
4.load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。
5.use(使用):作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎,每当虚拟机遇到一个需要使用变量的值的字节码指令时将会执行这个操作。
6.assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋值给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。
7.store(存储):作用于工作内存的变量,把工作内存中的一个变量的值传送到主内存中,以便随后的write的操作。
8.write(写入):作用于主内存的变量,它把store操作从工作内存中一个变量的值传送到主内存的变量中。
happens-before与重排序:
为了提高程序的性能,编译器和处理器经常会对指令进行重排序,如果JMM不对这种行为进行限制的话,就会造成多个线程并发时结果与我们期望的不符.
定义happen-before就是为了解决JMM中的一致性问题,一致性问题涉及到了可见性和有序性两种特性,但是不包含原子性,定义如下:
1.程序顺序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作
2.监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的加锁
3.volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读
4.传递性:如果A happens-before B,且B happens-before C,那么A happens-before C
5.start规则:如果线程A执行操作ThreadB.start()(启动线程B),那么A线程的ThreadB.start()操作happens-before于线程B中的任意操作
6.join规则:如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作happens-before于线程A从ThreadB.join()操作成功返回。
即只要不改变程序的执行结果,编译器和处理器怎么优化都行。happens-before这么做的目的,都是为了在不改变程序执行结果的前提下,尽可能地提高程序执行的并行度。
参考网页:
https://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html(内存模型定义了如何从内存中存取数据)
https://blog.csdn.net/bjweimengshu/article/details/79597938(JMM与Java内存结构的区别)
https://www.jianshu.com/p/1508eedba54d (happen-before原则解释)
阅读更多
- hbase LSM树个人理解
- 个人猜想的web安全——理解PHP的sessionID的实现
- 深度学习U-net个人理解
- 关于多维数组的一点个人的理解(以三维数组为例)
- 个人关于模块化的理解
- OW+框架的个人理解
- 关于malloc和free个人的一点理解
- JVM--从volatile深入理解Java内存模型
- 网页简介及个人理解
- 抽象工厂模式的个人理解
- [转]个人对AutoResetEvent和ManualResetEvent的理解
- 关于C#中 out/ref的一些个人理解
- 深入理解Java内存模型
- 内存控制理解(个人)
- android IPC机制简要个人理解(可能有差错 日后再来修改)
- 深入理解Java内存模型——volatile
- 深入理解Java内存模型(三)——顺序一致性
- HTTP的请求个人理解汇总
- java中WeakHashMap的个人理解
- 深入理解Java虚拟机--java内存模型与线程