概念

Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范。

JMM - 图2

JMM - 图3

补充:java内存模型中规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,首先要将变量从主内存拷贝的自己的工作内存空间,然后对变量进行操作,操作完成后再将变量写回主内存,不能直接操作主内存中的变量,工作内存中存储着主内存中的变量**副本拷贝**。工作内存是每个线程的私有数据区域,因此不同的线程间无法访问对方的工作内存,线程间的通信(传值)必须通过主内存来完成。


存在的问题

1.可见性问题

线程A和线程B同时操作共享数据C,线程A修改的结果,线程B是不知道的,即不可见的

2.竞争问题

刚开始数据C的值为1,线程A和线程B同时执行加1操作,正常情况下数据C应该为3,但是在并发的情况下,数据C却还是2

3.重排序问题

JVM为了优化指令的执行效率,会对一下代码指令进行重排序。

如何解决

原子性

通过synchronized关键字来实现。具体synchronized的原理见:synchronized 关键字

可见性

Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值的这种依赖主内存作为传递媒介的方式来实现的。 Java中的volatile关键字提供了一个功能,那就是被其修饰的变量在被修改后可以立即同步到主内存,被其修饰的变量在每次使用之前都从主内存刷新。因此,可以使用volatile来保证多线程操作时变量的可见性。 除了volatile,Java中的synchronized和final两个关键字也可以实现可见性。final 关键字

有序性

使用synchronized和volatile来保证多线程之间操作的有序性。volatile 关键字