深入JVM 原子性、可见性、有序性

Java内存模型围绕着并发过程中如何处理原子性、可见性和有序性三个特征来建立的

——原子性

由Java内存模型来直接保证原子性操作包括Read Load Assign Use Store Write可以认为基本数据类型的读写访问具备原子性,如果应用场景需要一个更大范围的原子性保证,Java内存模型提供Lock Unlock操作来提供支持,尽管虚拟机未把Lock Unlock操作直接开放接口使用,但提供了更高层的字节码指令MonitorEnter和MonitorExit来隐式的使用这两个操作,反映到程序设计人员的语言层面则是synchornized关键字,同步关键字,使得线程互斥的访问执行

——可见性

可见性体现为当一个线程修改了共享变量的数值时,其它线程能立即得知这个修改。如Volatile变量能够保证变量在多线程并发环境下的可见性。Java内存模型通过在变量修改后将新值同步回主内存,在读取变量前从主内存刷新变量值到线程所在的工作内存中,通过这类方式确保可见性,无论普通变量和volatile变量都是如此,但2者区别在于volatile变量能保证线程修改后立即刷新到主内存,以及每次读取时总是从主内存刷新最新的值,这一点普通变量不能保证

除volatile之外,Java语言提供synchronized和final 同步块的可见性是由“对一个变量执行Unlock操作前,必须先将此变量同步回主内存” 这一约束所确保的,而final关键字的可见性:被final关键字修饰的字段在构造器中一旦初始化,并且构造器没有把this引用传递出去,那么其它线程就能看见final字段

——有序性

Java内存模型的有效性,天然的有序性

  • 如果在本线程内观察,所有操作都是有序的,线程内部表现为串行
  • 如果在一个线程中观察另一个线程,所有操作都是无序的,主要是指令重排序和主内存 工作内存同步延迟造成的

Java语言提供volatile和synchornized关键字保证线程之间操作的有序性,volatile关键字本身禁止重排序,而synchornized关键字“一个变量同一时刻只允许一个线程对其进行Lock操作”这一约束确保,进一步讲,即持有同一个锁的两个同步块只能串行执行

从语言层面上讲,synchornized关键字能确保并发环境中这3个特性,但是由于其并发控制粒度很大,导致其并发性能很低

猜你喜欢

转载自blog.csdn.net/qq_33369979/article/details/88596696