Java内存模型与多线程数据可见性和操作的有序性

CPU在计算的时候,并不总是从内存读取数据,而是按:寄存器->高速缓存->内存的顺序读取,一些使用频繁的数据会被放在寄存器和高速缓存中,当线程计算完后,这些缓存的数据在适当的时候被写回内存,当多个线程同时读取某个内存的数据时,会涉及到数据的可见性操作的有序性问题。
Java是平台无关性语言,JLS(java语言规范)定义了一个统一的内存管理模型JMM(Java Memory Model),JMM屏蔽了底层平台管理内存的细节,在多线程环境中必须解决可见性和有序性的问题。JMM规定了JVM有主内存(Main Memory)工作内存(Working Memory),主内存就是我们平时所说的java堆内存,存放程序中所有的类实例、静态数据等变量,是多个线程共享的,而工作内存存放的是该线程从主内存中拷贝过来的变量以及访问方法取得的局部变量,是每个线程私有的其它线程不能访问的,每个线程对变量的操作都是以先从主内存将其拷贝到工作内存再对其进行操作的方式进行,多个线程之间不能直接相互传递数据通信,只能通过共享变量来进行。


数据可见性
多个线程之间是不能互相传递数据通信的,他们之间沟通只能通过共享变量来进行。Java内存模型规定了jvm有主内存,主内存是多个线程共享的,当new一个对象的时候,也是被分配在主内存中,每个线程都有自己独立的 工作内存,工作内存存储了主存的某些对象的副本,所以单个线程与线程的工作内存之间就有了相互隔离的效果,这就是“可见性问题”


操作的有序性
线程在引用变量时不能从主存中直接引用,如果线程工作内存中没有该变量,则会从主内存中拷贝一个副本到工作内存中,这个过程为read-load,完成后线程会引用该副本,当同一线程再度引用该字段时,有可能重新从主存中获取变量副本(read-load-use),也可能直接引用原来的副本,也就是说read/load/use的顺序可以有JVM实现系统决定。这个时候线程与线程之间的操作的先后顺序,会决定程序对主存区最后的修改是不是正确的,这就是“时序性问题”

你可能感兴趣的:(----【Java核心API】,编程体系相关基础,JavaEE专业技能)