volatile 关键字实战

x33g5p2x  于2022-04-06 转载在 其他  
字(1.6k)|赞(0)|评价(0)|浏览(279)

一 代码

package concurrent.volatileDemo;

import java.util.concurrent.TimeUnit;

public class VolatileFoo {
    // init_value 的最大值
    final static int MAX = 5;
    // init_value 的初始值
    // 不使用 volatile
    static int init_value = 0;
    // 使用 volatile
    //static volatile int init_value = 0;

    public static void main(String[] args) {
        // 启动一个 Reader 线程,当发现 local_value 和 init_value 不同时,则输出 init_value 被修改的信息
        new Thread(() -> {
            int localValue = init_value;
            while (localValue < MAX) {
                if (init_value != localValue) {
                    System.out.printf("The init_value is update to [%d]\n", init_value);
                    // 对 localValue 进行重新赋值
                    localValue = init_value;
                }
            }
        }, "Reader").start();

        // 启动 uddater 线程,主要用于对 init_value 的修改,当 local_value >= 5 时,退出
        new Thread(() -> {
            int localValue = init_value;
            while (localValue < MAX) {
                // 修改 init_value
                System.out.printf("The init_value will be changed to [%d]\n", ++localValue);
                init_value = localValue;
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Updater").start();
    }
}

二 当 init_value 不使用 volatile 时的测试结果

The init_value will be changed to [1]

The init_value will be changed to [2]

The init_value will be changed to [3]

The init_value will be changed to [4]

The init_value will be changed to [5]

三 当 init_value 使用 volatile 时的测试结果

The init_value will be changed to [1]

The init_value is update to [1]

The init_value will be changed to [2]

The init_value is update to [2]

The init_value will be changed to [3]

The init_value is update to [3]

The init_value will be changed to [4]

The init_value is update to [4]

The init_value will be changed to [5]

The init_value is update to [5]

四 说明

当 init_value 不使用 volatile 时,Reader 线程压根就没有感知到 init_value 的变化而进入了死循环,当加了 volatile ,Reader 线程就能感知到 init_value 的变化。这个巨大的变化就是这个小小的  volatile 起到的作用,从这个例子来看,volatile 使得共享变量在不同的线程可见。

相关文章