volatile

作者: 奔波儿灞_q | 来源:发表于2020-11-26 15:31 被阅读0次

    1.禁止指令重排序

    ``
    public class VoliatlieTest3 {

    private volatile VoliatlieTest3 singleInstace;
    
    private VoliatlieTest3() {
    }
    
    public VoliatlieTest3 getSingleInstace() {
        if (singleInstace == null) {            
            synchronized (VoliatlieTest3.class) {
                if (singleInstace == null) {
                    singleInstace = new VoliatlieTest3();
                }
            }
        }
        return singleInstace;
    }
    

    }
    ``
    singleInstace = new VoliatlieTest3()
    这个代码分3个指令:
    1.分配内存空间
    2.初始化对象
    3.将singleTon指向分配的内存
    第二步和第三步可能会次序不一样

    那么多线程这里会出问题
    现在有线程A,B
    如果A线程运行到singleInstace = new VoliatlieTest3(),并且这里指令被重新排序了,现在执行执行了
    1.分配内存空间
    2.将singleInstace指向分配的内存
    执行到这里的时候singleInstace就!= null了,但实际还是空的
    这个时候线程B正好过来了,判断singleInstace 不为空,然后返回了,此时B线程返回的就是空的对象

    2.保证对象(基本数据类型)可见性,

    ``
    public class VoliatlieTest2 extends Thread {

    //这里  volatile 会使线程内存中的变量从主内存中获取flat,如果没有这个关键字,则下面的进程不会退出,每次打印的i都是不一样的;
    volatile boolean flat = false;
    int i = 0;
    
    @Override
    public void run() {
        while (!flat) { i++; }
    }
    
    public static void main(String[] args) {
        VoliatlieTest2 voliatlieTest2 = new VoliatlieTest2();
        voliatlieTest2.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        voliatlieTest2.flat = true;
        System.out.println(voliatlieTest2.i);
        System.out.println(voliatlieTest2.i);
    }
    

    }
    ``
    主线程里面,flat 初始值是false, i初始值是0
    子线程voliatelieTest2启动起来后,如果flat是false对i进行++,主线程休眠1秒主线程将flat改为true
    打印2次i的变量
    这里虽然将flat改为true了,但是子线程还会对执行i++,可以理解为子线程操作的是自己内存中的那个flat, 没有和主线程中的flat进行同步,主线程的flat被改为true了 但是子线程读取的flat还是flase,如果flat用volatile修饰,主线程将flat改为true后,子线程读取的flat就会是true 也就是i++就不会再执行了,打印的值就是相同的数

    相关文章

      网友评论

          本文标题:volatile

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