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

发布于 2022-09-12 12:56:26 字数 247 浏览 28 评论 0

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

峩卟喜欢 2022-09-19 12:56:26

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

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

2022-09-19 12:56:26

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

提笔书几行 2022-09-19 12:56:26

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文