深解JVM 4-JMM内存模型

发布时间:2022-06-08 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了深解JVM 4-JMM内存模型脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

Java内存模型(Java Memory Model, JMM)。

Java内存模型是围绕着并发编程中原子性、可见性、有序性这三个特征来建立的。

原子性-AtomicITy

一个操作不能被打断,要么全部执行完毕,要么不执行。在这点上有点类似于事务操作,要么全部执行成功,要么回退到执行该操作之前的状态。

可见性

一个线程对共享变量做了修改之后,其他的线程立即能够看到(感知到)该变量的这种修改(变化)。

有序性

对于一个线程的代码而言,我们总是以为代码的执行是从前往后的,依次执行的。这么说不能说完全不对,在单线程程序里,确实会这样执行;但是在多线程并发时,程序的执行就有可能出现乱序。

用一句话可以总结为:在本线程内观察,操作都是有序的;如果在一个线程中观察另外一个线程,所有的操作都是无序的。前句是指“线程内表现为串行语义(WithIn Thread As-if-serial SEMantics)”,后半句是指“指令重排”现象和“工作内存和主内存同步延迟”现象。

 

关键词synchronized与volatile总结synchronized的特点一个线程执行互斥代码过程如下:

1、获得同步锁;2、清空工作内存;3、从主内存拷贝对象副本到工作内存;4、执行代码(计算或者输出等);5、刷新主内存数据;6、释放同步锁。所以,synchronized既保证了多线程的并发有序性,又保证了多线程的内存可见性。

volatile是第二种Java多线程同步的手段,根据JLS的说法,一个变量可以被volatile修饰,在这种情况下内存模型确保所有线程可以看到一致的变量值

@H_512_38@
    class test {  
        static volatile int i = 0, j = 0;  
        static void one() {  
            i++;  
            j++;  
        }  
        static void two() {  
            System.out.PRintln("i=" + i + " j=" + j);  
        }  
    }  

加上volatile可以将共享变量i和j的改变直接响应到主内存中,这样保证了i和j的值可以保持一致,然而我们不能保证执行two方法的线程是在i和j执行到什么程度获取到的,所以volatile可以保证内存可见性,不能保证并发有序性(不具有原子性)。如果没有volatile,则代码执行过程如下:

1、将变量i从主内存拷贝到工作内存;2、刷新主内存数据;3、改变i的值;4、将变量j从主内存拷贝到工作内存;5、刷新主内存数据;6、改变j的值;

重排序在执行程序时为了提高性能,编译器和处理器常常会对指令做重排序。重排序分三种类型:

1、编译器优化的重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。2、指令级并行的重排序。现代处理器采用了指令级并行技(Instruction-Level Parallelism, ILP)来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。3、内存系统的重排序。由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行。

(37条消息) JMM概述_牧竹子的博客-CSDN博客_jmm

 

脚本宝典总结

以上是脚本宝典为你收集整理的深解JVM 4-JMM内存模型全部内容,希望文章能够帮你解决深解JVM 4-JMM内存模型所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。