当前位置: 首页 > 知识库问答 >
问题:

线程卡住忙等待在某些情况下,而不是在其他情况下

强安和
2023-03-14

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

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

while(OtherThread.countInt < 5);

如果我使用上面的代码,线程将被卡在忙等待中,不会跳出while循环,即使静态int count tInt确实达到5。

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

但是,如果我使用其他代码,那么线程确实会跳出忙等待循环。有时,一旦count tInt达到5,其他时候会晚一点。但它会发生。对于我的特定示例,我将其用作“无意义的工作”

< code>print("忙着等待...",1000) //浪费时间做无意义的工作

其中我将< code>print定义为< code >同步静态void print(String s,int n)打印字符串< code>s,然后Hibernate< code>n毫秒。

什么给你?为什么线程忙于等待第一个代码,而不是另一个代码?所有线程都具有相同的优先级,所以这不可能是优先级问题。

共有1个答案

全弘深
2023-03-14

countInt不是易失性,因此不能保证等待线程可以看到更改。

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

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

学习Java的并发支持也很有帮助。线程间的通信是很重要的。

 类似资料:
  • 我用Kotlin和Jongo来访问MongoDB。Jongo使用Jackson来序列化/反序列化对象,以便从MongoDB中保存和读取它们。我使用Jackson-Kotlin模块来帮助使用构造函数序列化Kotlin数据类。 下面是一个序列化良好的数据类的示例: 下面是一个未能反序列化的类似类的示例: Jongo抛出以下异常,因为Jackson反序列化失败: 如果我像这样完整地注释会话数据类,它确实

  • Java/Selenium WebDriver/Firefox 页面上有一个文本“输入”字段。然后它下面有一个‘提交’按钮。加载页面时,输入字段和提交按钮都已启用。在输入字段中输入文本后,是否有一种方法让WebDriver在点击Submit按钮之前等待“x”秒,而不是立即点击它。

  • Project Reactor是否可以在一个mono中等待一个事件/条件,而不需要使用每个mono的阻塞线程?使用,我可以完成这样的事情,但我不知道如何使用Project Reactor。 我的问题是我需要将请求与响应相关联。响应时间变化很大,有些甚至永远不会得到回复和超时。在客户端,每个请求阻塞线程不是问题,但由于这是一个服务器应用程序,我不想最终导致每个请求产生一个线程阻塞等待响应。 API如

  • 我目前正在承担一个项目,我正在使用Java微基准线束(JMH)框架测量Java中不同类型循环的速度。我得到了一些关于流的有趣结果,我无法解释,并且想知道是否更了解流和数组列表的人可以帮助我解释我的结果。 基本上,当遍历大小为100的数组列表时,stream.forEach方法比任何其他类型的循环都快得多: 我的结果图表显示在这里:https://i.imgur.com/ypXoWWq.png 我尝

  • 问题内容: 鉴于以下课程 当我们验证它(例如,使用@Valid)并且如果Website.url不遵守我的自定义@ValidUrl约束时,我们将遇到约束冲突(例如,“ URL不可访问”)。 我想知道如果用户愿意,是否可以忽略该验证。 脚步: 第一次验证表格 引发约束冲突并将其显示给用户 用户选择“我知道,仍然添加”,然后重新提交 第二次验证表单,验证@ValidUrl以外的所有内容 问题答案: 您可

  • 问题内容: 我想创建一个触发器,以防止在出生日期(列之一)将来的时候插入。我有这个: 如何取消if语句中的插入? 问题答案: 基于这一点,我不确定是否可以这样做。 MySQL当前的触发器实现中不支持自愿引发异常并中止生成触发器的语句。 我发现的解决方法是编写一个BEFORE触发器,以将表中的not-NULL列之一设置为NULL,从而违反了其NOT NULL约束。这导致产生触发器的语句被中止。