请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

volatile做信号量的疑问

  • 信号量不用volatile修饰不也可以吗?
  • 我写了个信号量的demo如下,去掉volatile也完全可以啊?
public class VolatileDemo1 {

    public static volatile boolean inited = false;
    public static int var = 0;

    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();

        service.execute(() -> {
            try {
                TimeUnit.MILLISECONDS.sleep(2);
                var = -1;
                inited = true;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        service.execute(() -> {
            while (!inited) {
                System.out.println(var++);
            }
            System.out.println(var);
        });

        service.shutdown();
    }

}

正在回答

1回答

Jimin 2019-03-27 23:11:40

你好,信号量里使用volatile主要是利用他的可见性。使用了volatile后,可以保证每次读都是内存里最新的值,这样可以保证做到,只要volatile修饰的变量发生了变化,那么下次循环就一定能按照变化后的值进行操作。放过来讲,没有volatile修饰,那么由于不具备可见性,某个线程里修改了共享变量,其他线程是不确定什么时候能过来读取到最新的值的。但是,这不代表其他线程永远读取不到最新的值。

因此,去掉volatile不代表一定会永远读取不到最新的值,这个可以类比线程不安全问题,有些代码尽管有线程不安全的风险,但这不代表一定会触发线程不安全。从实际角度出发,做为一个信号量,我们预期的肯定是只要这个信号发生变化,其他使用这个信号的地方都能立即感知到。

1 回复 有任何疑惑可以回复我~
  • 提问者 磊磊要酷酷滴 #1
    翻阅了老师提到的《深入理解Java虚拟机 第2版》中关于volatile的讲述,此处加volatile修饰,还能禁止指令重排的问题,避免在最后一行对信号量的修改操作提前到前面运行;加上老师解释的,volatile让信号量在修改后,对其他线程立马可见,对volatile的理解更深刻了;谢谢老师的耐心讲解^_^
    回复 有任何疑惑可以回复我~ 2019-03-29 15:01:04
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信