Fork me on GitHub

JMM内存模型

java内存模型(Java Memory Module)

虚拟机并不是直接操作主内存,而是又创建了一个缓存,类似cpu的高速缓存,要操作内存中的数据,一般会进行多步原子操作,这就会导致多个线程访问会出现一些问题。

JMM的原子操作如下图说明

volatile关键字

/**
 * 循环里有代码,则会跳出循环,不知道什么原因
 */
public class VolatileTest {
    private static  boolean flag = false; // 不适用volatile修饰,可能会进入死循环
    public static void main(String[] args){
        new Thread(()->{
            while (!flag){
                ///System.out.println("flag已修改"); 循环里有代码,则会跳出循环,不知道什么原因
            }
            System.out.println("线程1停止");
        }).start();

        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("修改flag的值");
            flag = true;
        }).start();
    }
}

并发编程三大特性:可见性,有序性,原子性。volatile能保证可见性和有序性,有两个主要作用,可见和禁止代码重排

可见性:一个线程修改了某个共享变量的值,另一个线程可以感知到

指令重排:在不影响单线程执行结果的情况下,计算机为了最大限度的利用cpu的性能,会对机器指令重排优化

重排的原则:as-if-serial和happen-before

volatile的实现原理:利用CPU的缓存一致性协议MESI,volatile马上将改变的变量写入主内存并开始MESI协议

双重检测锁实现的单例,对象半初始化:由于指令重排的关系,可能会先执行对象闯将的init()方法,然后再执行putstatic,单线程没问题,但多线程会有问题

class DoubleCheckInstance{
    private static DoubleCheckInstance instance = null;
    // 建议添加volatile关键字,避免代码重排
    // private static volatile DoubleCheckInstance instance = null;

    private DoubleCheckInstance(){}
    
    public static DoubleCheckInstance getInstance() {
        if(instance == null){// 如果a, b线程同时执行到这一步,符合判断,进入同步代码块
            synchronized (DoubleCheckInstance.class){
                if(instance == null){ // 如果这里没有判断,则总是会执行new对象代码
                    instance = new DoubleCheckInstance();  // 创建对象有三个指令1. 分配对象的内存空间 2. 初始化对象 3. 设置instance指向刚分配的内存地址
                    // 可能会出现指令重排的情况,导致先执行3,在执行2,如果是单线程没有问题,多线程就会有问题
                }
            }
        }
        return instance;
    }
}

https://blog.csdn.net/qq_37960603/article/details/103944203
https://blog.csdn.net/DJYDFT2831djydft/article/details/113773631
volatile关键字说明

volatile保证有序性:使用内存屏障,JVM规范定义的内存屏障,可以保证指令的顺序

posted @ 2021-03-03 14:20  Catalinas  阅读(64)  评论(0编辑  收藏  举报