java线程sleep结束后是否会刷新工作内存?

新手上路,请多包涵

image
在main函数里执行Thread.sleep(2000); 之后更新了未用volatile修饰的变量flag,然而线程并没有停下来。将Thread.sleep(2000); 注释掉后线程就会停下来。我个人的理解是线程唤醒后并没有更新flag到工作内存。但是直接更新flag,线程停了下来,说明把更新后的flag读到了工作内存。这是为何?

阅读 3.4k
3 个回答

volatile 保证一定会刷新,但是不volatile也不一定其他线程看不见;
我在我本地测试, 用您的代码, sleep(0)和sleep(1)是可以刷的;sleep(2)或者2ms以上就不行了;
因为main线程和t子线程是并行执行的, 有可能:
子线程run之前,main线程sleep时, 后面的flag赋值完成, 也做了刷新; 但是这不是一定的;

我们记得volatile是肯定刷的就行了, 非volatile的可能刷, 也可能不刷, 确定性不能保证.

代码中并没有happens before保障,所以不一定会刷新

新手上路,请多包涵

当取消sleep后,你的Thread2线程可能还没运行起来呢,就被主线程将flag改为false了,读到Thread2工作内存中的flag就是false,所以直接就停了,此时的i应该是0,因为根本没读到过值为true的flag。
使用sleep是确保Thread2线程已经运行起来,之后再修改flag为false。因为没有可见性保证,所以Thread2工作内存中的flag一直是true,无法停下来。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题