问题一:为什么要学习JMM内存模型
在我们学习Java的第一天就了解到Java是一门通过JVM虚拟机跨平台的语言,同时Java也是一门具有多个线程同时处理能力的编程语言,那么在多个线程并发的情况,我们的Java底层是如何对这些线程进行处理,且又如何保证线程的安全性,这就是学习JMM内存模型的原因以及目的
并发编程分类
并发编程解决的问题是多个线程在怎么样交互数据,简单的说,就是多个线程在处理同一个变量时,如何进行信息的沟通,当下流行的一共有两种通信的机制
1.共享内存
在这种内存模型下,会产生工作内存(将共享数据加载到工作内存中来进行操作,保证数据的高效性)和主内存(存放共享数据),工作内存和主内存之间通过read 和 write 来进行数据的交流
2.消息传递
这种模型是没有共享数据,线程之间必须通过明确的发送消息来显式进行通信。
内存模型的工作方式
Java采用的是共享内存模型
正如上文所介绍的那样,Java会将共享的数据放置到主内存中,当多个线程操作这个共享变量时,会将对应的内容加载到自己的工作内存中来,也就是说,有多少个线程就有多少个工作内存
假设现在有内存A和B有主内存中共享变量x的副本。初始时,这三个内存中的x值都为0。线程A在执行时,把更新后的x值(假设值为1)临时存放在自己的本地内存A中。当线程A和线程B需要通信时,线程A首先会把自己本地内存中修改后的x值刷新到主内存中,此时主内存中的x值变为了1。随后,线程B到主内存中去读取线程A更新后的x值,此时线程B的本地内存的x值也变为了1。
从整体来看,这两个步骤实质上是线程A在向线程B发送消息,而且这个通信过程必须要经过主内存。JMM通过控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证。内存模型中值得注意的三个点
1. 内存可见性
内存可见性的问题指的就是在工作方式中介绍到当A修改了工作内存中的数据,此时B去操作自己工作内存中的数据时, A需要将数据写回到主内存中,B再次从主内存中读取数据,但这有可能情况并不是那么美好,若B没有从主内存中读取数据,那么此时B中的数据和A中的数据此刻将变得没有意义,所以我们将这重在修改了各自工作内存后,没有重新从主内存中读取数据的行为,称之为内存可见性问题,A和B彼此之间数据不可见
在我们学习Java的第一天就了解到Java是一门通过JVM虚拟机跨平台的语言,同时Java也是一门具有多个线程同时处理能力的编程语言,那么在多个线程并发的情况,我们的Java底层是如何对这些线程进行处理,且又如何保证线程的安全性,这就是学习JMM内存模型的原因以及目的
并发编程分类
并发编程解决的问题是多个线程在怎么样交互数据,简单的说,就是多个线程在处理同一个变量时,如何进行信息的沟通,当下流行的一共有两种通信的机制
1.共享内存
在这种内存模型下,会产生工作内存(将共享数据加载到工作内存中来进行操作,保证数据的高效性)和主内存(存放共享数据),工作内存和主内存之间通过read 和 write 来进行数据的交流
2.消息传递
这种模型是没有共享数据,线程之间必须通过明确的发送消息来显式进行通信。
内存模型的工作方式
Java采用的是共享内存模型
正如上文所介绍的那样,Java会将共享的数据放置到主内存中,当多个线程操作这个共享变量时,会将对应的内容加载到自己的工作内存中来,也就是说,有多少个线程就有多少个工作内存
假设现在有内存A和B有主内存中共享变量x的副本。初始时,这三个内存中的x值都为0。线程A在执行时,把更新后的x值(假设值为1)临时存放在自己的本地内存A中。当线程A和线程B需要通信时,线程A首先会把自己本地内存中修改后的x值刷新到主内存中,此时主内存中的x值变为了1。随后,线程B到主内存中去读取线程A更新后的x值,此时线程B的本地内存的x值也变为了1。
从整体来看,这两个步骤实质上是线程A在向线程B发送消息,而且这个通信过程必须要经过主内存。JMM通过控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证。内存模型中值得注意的三个点
1. 内存可见性
内存可见性的问题指的就是在工作方式中介绍到当A修改了工作内存中的数据,此时B去操作自己工作内存中的数据时, A需要将数据写回到主内存中,B再次从主内存中读取数据,但这有可能情况并不是那么美好,若B没有从主内存中读取数据,那么此时B中的数据和A中的数据此刻将变得没有意义,所以我们将这重在修改了各自工作内存后,没有重新从主内存中读取数据的行为,称之为内存可见性问题,A和B彼此之间数据不可见