Java中的volatile关键字最全总结(四)

pivoteic
发布于 2022-6-15 17:05
浏览
0收藏

 

volatile的应用场景

由于volatile的特性,使得它适用于一些纯赋值的场景,对于一些非原子性的操作,比如:i++,volatile就不适合了,看一个例子:

public class VolatileDemo {
    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        Thread t1 = new Thread(myThread);
        Thread t2 = new Thread(myThread);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(myThread.flag);
        System.out.println(myThread.atomicInteger);
    }
}

class MyThread implements Runnable {

    public volatile boolean flag = false;
    public AtomicInteger atomicInteger = new AtomicInteger(0);

    @Override
    public void run() {
        for (int i = 0; i < 5000; i++) {
            change();
            atomicInteger.incrementAndGet();
        }
    }

    private void change() {
        flag = true;
    }
}


对于这个程序,输出的flag结果永远只能是true,但是如果将 flag = true 修改为 flag = !flag ,这就不是一个原子性的操作了,此时程序就会出现true或false的两种输出结果。

volatile还可用于变量的触发器,前面我们了解过happens-before原则,当某个volatile修饰的变量被赋值后,其它线程在获取该变量时,该变量及其之前的操作对其它线程均是可见的,例如:

public class VolatileDemo {

    private int a = 1;
    private int b = 2;
    private int c = 3;
    private volatile boolean flag = false;

    private void write() {
        a = 3;
        b = 4;
        c = 5;
        flag = true;
    }

    private void read() {
        while (flag) {
            System.out.println("a=" + a + ",b=" + b + ",c=" + c);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        VolatileDemo volatileDemo = new VolatileDemo();
        while (true) {
            new Thread(() -> {
                volatileDemo.write();
            }).start();
            new Thread(() -> {
                volatileDemo.read();
            }).start();
        }
    }
}


在read()方法中,当flag值为true时会输出变量a、b、c的值,而如果flag为true的话,那么为flag赋值之前的操作都将是可见的,所以变量a、b、c的值一定分别是3、4、5,这就相当于一个触发器,当触发器变量满足条件时,刷新之前的变量得到最新值,触发器典型的应用场景就是Web容器的初始化。

本文作者:汪伟俊 为Java技术迷专栏作者 投稿,未经允许请勿转载

 

文章转自公众号:三友的java日记

标签
已于2022-6-15 17:05:19修改
收藏
回复
举报
回复
    相关推荐