我有一个非常奇怪的问题,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
毫秒。
是什么给出的?为什么线程忙于等待第一个代码,而不是另一个?所有线程都有相同的优先级,因此它不是优先问题。
答案 0 :(得分:3)
countInt
不是volatile
,因此保证等待线程无法看到更改。
由于您的print()
方法为synchronized
,因此可能会产生足够的内存屏障,导致更新的值对您的while
循环可见。这基本上是巧合; while
条件本身仍然存在。这就是正确设计和测试并发代码如此重要的原因 - 只有出现才能按预期工作,但稍后会失败(例如,在负载下,在不同的处理器上,在看似安全的重构之后,等等。)。
使用适当的内存屏障,例如synchronised
读写,volatile
字段或跨线程通信机制,例如java.util.concurrent
中的那些。有许多related questions探索volatile
以及其他这些工具。
你也可以学习Java's concurrency support。跨线程通信并非易事。