Java 线程在某些情况下忙着等待,而在其他情况下则不忙
我遇到了一个非常奇怪的问题,java线程正忙着等待 我有一个线程忙着等待另一个线程的静态变量的状态。假设busy等待的线程正在等待另一个线程的静态int变量达到某个值Java 线程在某些情况下忙着等待,而在其他情况下则不忙,java,multithreading,busy-waiting,Java,Multithreading,Busy Waiting,我遇到了一个非常奇怪的问题,java线程正忙着等待 我有一个线程忙着等待另一个线程的静态变量的状态。假设busy等待的线程正在等待另一个线程的静态int变量达到某个值 while(OtherThread.countInt < 5); 但是,如果我使用另一个代码,那么线程会突破繁忙的等待循环。有时,只要countInt达到5,其他时间稍晚。但它确实发生了。在我的例子中,我把这当作“无意义的工作” print(“忙着等待…”,1000)//浪费时间做无意义的工作 其中,我将print定义为同
while(OtherThread.countInt < 5);
但是,如果我使用另一个代码,那么线程会突破繁忙的等待循环。有时,只要countInt
达到5,其他时间稍晚。但它确实发生了。在我的例子中,我把这当作“无意义的工作”
print(“忙着等待…”,1000)//浪费时间做无意义的工作
其中,我将print
定义为同步静态无效打印(String s,int n)
,它打印Strings
,然后休眠n
毫秒
有什么好处?为什么线程总是忙于等待第一个代码,而不是另一个?所有线程都具有相同的优先级,因此这不是优先级问题。
countInt
不是易变的,因此不能保证等待的线程可以看到更改
由于您的print()
方法是synchronized
的,因此可能会创建一个足够的内存屏障,使更新的值在循环时对可见。这本质上是巧合;而
条件本身仍然被破坏。这就是为什么正确地设计和测试并发代码是如此重要的原因——编写一些看起来只能按预期工作,但以后会失败的代码是很容易的(例如,在负载下,在不同的处理器上,在看似安全的重构之后,等等)
使用适当的内存屏障,如同步
读写、易失性
字段或跨线程通信机制,如中的机制。有许多探索volatile
和这些其他工具
你也应该好好学习。跨线程通信是非常重要的。这是countInt
一个易失性的
字段吗?//浪费一些时间做一些没有意义的工作“为什么不等一个countdownlock
或信号灯
?我想要一个非常简单的例子。我认为它不会比只打印到控制台然后休眠几秒钟更简单。@Thilo在问题中它被指定为“static int countInt
”。这如何解释第二个繁忙等待循环(线程在主体中工作的循环)的爆发?编辑:忘了提了,谢谢你的资源。“我一定会调查的。”曼纽尔在我的回答中补充了一些细节。
while(OtherThread.countInt < 5) {
// waste some time doing meaningless work
}