线程在某些情况下仍然忙着等待而不是在其他情况下等待

时间:2016-11-27 23:33:43

标签: java multithreading busy-waiting

我有一个非常奇怪的问题,java线程忙等待。

我有一个忙于等待某个其他线程的静态变量状态的线程。让我们说忙等待的线程正在等待另一个线程的静态int变量达到某个值

while(OtherThread.countInt < 5);

如果我使用上面的代码,那么即使static int countInt达到5,线程也会处于忙碌等待状态并且不会突破while循环。

while(OtherThread.countInt < 5) {
    // waste some time doing meaningless work
}

但是,如果我使用其他代码,则 线程会突破忙等待循环。有时候,只要countInt达到5,有一段时间就会达到。但它发生了。对于我的具体例子,我用这个作为&#34;无意义的工作&#34;

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

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

是什么给出的?为什么线程忙于等待第一个代码,而不是另一个?所有线程都有相同的优先级,因此它不是优先问题。

1 个答案:

答案 0 :(得分:3)

countInt不是volatile,因此保证等待线程无法看到更改。

由于您的print()方法为synchronized,因此可能会产生足够的内存屏障,导致更新的值对您的while循环可见。这基本上是巧合; while条件本身仍然存在。这就是正确设计和测试并发代码如此重要的原因 - 只有出现才能按预期工作,但稍后会失败(例如,在负载下,在不同的处理器上,在看似安全的重构之后,等等。)。

使用适当的内存屏障,例如synchronised读写,volatile字段或跨线程通信机制,例如java.util.concurrent中的那些。有许多related questions探索volatile以及其他这些工具。

你也可以学习Java's concurrency support。跨线程通信并非易事。