Java并发编程之关键字volatile的使用

volatile关键字的作用

1.可以保证不同线程间volatile变量的一致性。但是不能保证原子操作。
2.可以禁止指令重排。

一致性

cpu会将经常使用的值加入到缓存中从而加快读取速度。每次修改变量的值时,首先会在缓存中完成修改,此时内存中的值还没有改变。(至于什么时候写回内存则不确定(会在合适的时候)这样就会出现并发问题)。用volatile修饰的变量会在值改变后,立即修改内存中的值。从而保证不同线程间volatile值的一致性。

例子

用volatile修饰

public class Test1 {
    
    
    //用volatile修饰
    volatile int temp = 0;
    int i = 0;
    public static void main(String[] args) throws InterruptedException {
    
    
        Test1 t1 = new Test1();
        Thread thread1 = new Thread(()->{
    
    
            t1.fun1();});
        Thread thread2 = new Thread(()->{
    
    
            t1.fun1();});
        Thread thread3 = new Thread(()->{
    
    
            t1.fun1();});
        Thread thread4 = new Thread(()->{
    
    
            t1.fun1();});
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
        Thread.sleep(1000);
        t1.temp = 1;
    }
    void fun1(){
    
    
        while (temp==0){
    
    
            
        }
    }
}

上述程序可以结束
在这里插入图片描述

volatile int temp = 0;改成int temp = 0;后此程序将一直循环下去。

禁止指令重排

JVM可以通过改变指令的执行顺序从而加快执行效率。(保证在本线程中的执行结果不变)

例子

public class Test3 {
    
    
    //双端检索模式中用volatile防止指令重排
    volatile static Test3 t3;
    static Test3 getTest3(){
    
    
        if(t3==null){
    
    
            synchronized (Test3.class){
    
    
                if(t3==null){
    
    
                    t3 = new Test3();
                }
            }
        }
        return t3;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_30033509/article/details/111875546