美文网首页
Java内存模型(JMM)

Java内存模型(JMM)

作者: kaixingdeshui | 来源:发表于2020-11-06 15:30 被阅读0次

Java内存模型(JMM)

由于并发程序要比串行程序复杂很多,其中一个重要原因是并发程序中数据访问一致性安全性将会受到严重挑战。

JMM关键技术点都是围绕着多线程的原子性、可见性、有序性来建立的。

原子性

原子性是指操作是不可分的,要么全部一起执行,要么不执行。
在java中,其表现在对于共享变量的某些操作,是不可分的,必须连续的完成。
java中实现原子操作的方法大致有2种:锁机制无锁CAS机制

可见性

可见性是值一个线程对共享变量的修改,对于另一个线程来说是否是可以看到的。

image.png

*我们定义的所有变量都储存在 主内存
*每个线程都有自己 独立的工作内存,里面保存该线程使用到的变量的副本(主内存中该变量的一份拷贝)
*线程对共享变量所有的操作都必须在自己的工作内存中进行,不能直接从主内存中读写(不能越级)
*不同线程之间也无法直接访问其他线程的工作内存中的变量,线程间变量值的传递需要通过主内存来进行。(同级不能相互访问)
线程需要修改一个共享变量X,需要先把X从主内存复制一份到线程的工作内存,在自己的工作内存中修改完毕之后,再从 工作内存中 回写到 主内存。
如果线程对变量的操作没有刷写回主内存的话,仅仅改变了自己的工作内存的变量的副本,那么对于其他线程来说是不可见的。

共享变量可见性的实现原理:
线程A对共享变量的修改要被线程B及时看到的话,需要进过以下步骤:
1.线程A在自己的工作内存中修改变量之后,需要将变量的值刷新到主内存中
2.线程B要把主内存中变量的值更新到工作内存中

关于 线程可见性 的控制,可以使用volatilesynchronized来实现。

有序性

指的是 程序 按照代码的 先后 顺序执行。

为了性能优化,编译器和处理器会进行指令冲排序,有时候会改变程序语句的先后顺序。

在单例模式的实现上有一种双重检验锁定的方式,代码如下:

public class Singleton {
     static Singleton instance;
     static  Singleton  getInstance(){
         if  (instance == null) {
             synchronized  (Singleton.class) {
                 if (instance == null)
                     instance = new Singleton();
             }
         }
         return instance;
     }
 }

先看 instance=newSingleton();

未被编译器优化的操作:
指令1:分配一款内存M
指令2:在内存M上初始化Singleton对象
指令3:将M的地址赋值给instance变量

编译器优化 后 的操作指令:
指令1:分配一块内存S
指令2:将M的地址赋值给instance变量
指令3:在内存M上初始化Singleton对象

现在比较好的做法就是采用静态内部类的方式实现:

public class Singleton {
    private Singleton(){
    }
    private static class SingletonHandler{
        private static Singleton instance = new Singleton();
    }
    public static Singleton getInstance(){
        return SingletonHandler.instance;
    }
}

相关文章

网友评论

      本文标题:Java内存模型(JMM)

      本文链接:https://www.haomeiwen.com/subject/loptbktx.html