首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程在某些情况下忙着等待,而不是在另一些情况下。

线程在某些情况下忙着等待,而不是在另一些情况下。
EN

Stack Overflow用户
提问于 2016-11-27 23:33:43
回答 1查看 394关注 0票数 1

我遇到了一个非常奇怪的问题,一个java线程忙着等待。

我有一个线程忙着等待其他线程的静态变量的状态。假设繁忙等待的线程正在等待另一个线程的静态int变量达到某个值

代码语言:javascript
复制
while(OtherThread.countInt < 5);

如果我使用上面的代码,即使static int countInt达到5,线程也会被阻塞-等待,并且不会从while循环中跳出。

代码语言:javascript
复制
while(OtherThread.countInt < 5) {
    // waste some time doing meaningless work
}

但是,如果我使用其他代码,那么线程就会从繁忙的等待循环中跳出。有时,当countInt达到5,其他时间后一段时间。但这确实发生了。对于我的特殊例子,我用它作为“毫无意义的工作”。

print("busy waiting...",1000) // wasting time doing meaningless work

其中,我将print定义为synchronzied static void print(String s, int n),它打印字符串s,然后休眠n毫秒。

怎么回事?为什么线程会忙着等待第一段代码,而不是另一段代码呢?所有线程都有相同的优先级,所以不可能是优先级问题。

EN

回答 1

Stack Overflow用户

发布于 2016-11-27 23:34:47

countInt不是volatile,因此该更改不能保证对等待线程可见。

由于您的print()方法是synchronized,很可能会创建一个足够的内存屏障,使更新的值在while循环中变得可见。这在本质上是一个巧合;while条件本身仍然被破坏。这就是为什么正确地设计和测试并发代码是如此重要的原因--很容易编写一些看起来只像预期的那样工作,但以后会失败的东西(例如,在负载下,在不同的处理器上,在看似安全的重构之后,等等)。

使用适当的内存屏障,如synchronised读写、volatile字段或跨线程通信机制(如java.util.concurrent中的机制)。有许多相关问题在探索volatile和这些其他工具。

你也可以很好地学习Java的并发支持。跨线程通信是不平凡的.

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40835156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档