Java volatile 示例及扩展

public class VolatileTest {

    private static boolean stop = false;

    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("start");
            long i = 0;
            System.out.println("i:" + i);
            while (!stop){
                i++;
            }

            System.out.println("stop;i:" + i);
        }, "volatileTestThread");
        thread.start();
        System.out.println("set stop start");
        stop = true;
        System.out.println("set stop end");
    }
}

结果: 

set stop start
set stop end
start
i:0
stop;i:0

 volatileTestThread还没有开始,main线程就执行到stop = true了,所以加上main线程休眠继续测试。

public class VolatileTest {

    private static boolean stop = false;

    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("start");
            long i = 0;
            System.out.println("i:" + i);
            while (!stop){
                i++;
            }

            System.out.println("stop;i:" + i);
        }, "volatileTestThread");
        thread.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("set stop start");
        stop = true;
        System.out.println("set stop end");
    }
}

结果:

start
i:0
set stop start
set stop end

如果stop没有volatile修饰,volatileTestThread不会终止。stop加上volatile修饰继续测试。

public class VolatileTest {

    private static volatile boolean stop = false;

    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("start");
            long i = 0;
            System.out.println("i:" + i);
            while (!stop){
                i++;
            }

            System.out.println("stop;i:" + i);
        }, "volatileTestThread");
        thread.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("set stop start");
        stop = true;
        System.out.println("set stop end");
    }
}

结果:

start
i:0
set stop start
set stop end
stop;i:-1320028603

 volatile保证了线程volatileTestThread对stop的可见性。

示例中while循环被终止了。i最终为负值,是因为i曾经加到Integer.MAX_VALUE,再加1就会成为最小值(-2147483648),然后继续加,还没加到0就stop为true退出循环了。请看示例:

        int ii = Integer.MAX_VALUE;
        // 2147483647
        System.out.println(ii); 
        ii++;
        // -2147483648
        System.out.println(ii);
        // true
        System.out.println(ii == Integer.MIN_VALUE);
        // -2147483647
        ii++;
        System.out.println(ii);

 扩展一下(即使不加volatile也能终止volatileTestThread的多种方式):

(1)启动参数(VM options)设置-Djava.compiler=NONE,关闭JIT编译器。

(2)循环体中有释放锁的操作,同步主内存。比如:

           while (!stop){
                i++;
                // println里面有同步代码块
                System.out.println(i);
            }

或:

            while (!stop){
                i++;
                // 同步代码块
                synchronized (VolatileTest.class){
                }
            }

(3)循环体中有IO操作:

            while (!stop) {
                i++;
                new File("test.txt");
            }

(4)循环体中线程sleep或者yield,CPU时间片切换:

            while (!stop) {
                i++;
                try {
                    Thread.sleep(0);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            while (!stop) {
                i++;
                Thread.yield();
            }

(5)循环体中的i被volatile修饰:

public class VolatileTest {

    private static boolean stop = false;
    
    private static volatile int i = 0;

    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("start");
            while (!stop) {
                i++;
            }

            System.out.println("stop;i:" + i);
        }, "volatileTestThread");
        thread.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("set stop start");
        stop = true;
        System.out.println("set stop end");
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风铃峰顶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值