我遇到了一个非常奇怪的问题,一个java线程忙着等待。
我有一个线程忙着等待其他线程的静态变量的状态。假设繁忙等待的线程正在等待另一个线程的静态int变量达到某个值
while(OtherThread.countInt < 5);如果我使用上面的代码,即使static int countInt达到5,线程也会被阻塞-等待,并且不会从while循环中跳出。
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毫秒。
怎么回事?为什么线程会忙着等待第一段代码,而不是另一段代码呢?所有线程都有相同的优先级,所以不可能是优先级问题。
发布于 2016-11-27 23:34:47
countInt不是volatile,因此该更改不能保证对等待线程可见。
由于您的print()方法是synchronized,很可能会创建一个足够的内存屏障,使更新的值在while循环中变得可见。这在本质上是一个巧合;while条件本身仍然被破坏。这就是为什么正确地设计和测试并发代码是如此重要的原因--很容易编写一些看起来只像预期的那样工作,但以后会失败的东西(例如,在负载下,在不同的处理器上,在看似安全的重构之后,等等)。
使用适当的内存屏障,如synchronised读写、volatile字段或跨线程通信机制(如java.util.concurrent中的机制)。有许多相关问题在探索volatile和这些其他工具。
你也可以很好地学习Java的并发支持。跨线程通信是不平凡的.
https://stackoverflow.com/questions/40835156
复制相似问题