【问题标题】:Object.wait() without spinning in JVMObject.wait() 没有在 JVM 中旋转
【发布时间】:2016-03-04 04:57:17
【问题描述】:

我有一个组件,其中线程轮询某些资源和System.currentTimeMillis();如果没有资源,他们会选择Object.wait(1),因为我知道我会等待至少 1 毫秒(当线程看到新的时间戳时会补充资源)。但是,在 JVM 中,Object.wait() 会导致 ObjectMonitor::TrySpin_VaryDuration,所以当我告诉它去睡觉时,线程正在烧 CPU。

有什么办法可以绕过它(具有类似语义的更好的同步原语?)但是重新设计组件以便线程进入无限睡眠并且只有一个线程忙于等待?或者我可以在这个对象上选择性地禁用它吗?

编辑:我的问题有点傻。正如公认的答案所说,我真的应该使用Thread.sleep(1)(除非它也使用自旋锁 - 尚未确认),因为在时间到了时唤醒等待线程是没有意义的,因为它们应该已经被超时唤醒了。

【问题讨论】:

  • 问题在于wait 的低参数:实现可能决定旋转等待而不是让步。你为什么不使用BlockingQueue 来完成任务?

标签: java multithreading concurrency threadpool spinlock


【解决方案1】:

Object.wait(1) 是错误的工作工具。请改用Thread.sleep(1)

【讨论】:

  • 这还不会导致有限等待吗?
  • Object.wait(1)的原因是当一个线程发现补足资源时,通知其他线程唤醒。另一方面,你是对的,无论如何它们都应该醒来,因为它们的时间到了。
【解决方案2】:

您可以尝试使用名为-XX:-UseSpinning的标志

【讨论】:

  • 谢谢,虽然这有点粗糙。并且不适用于现代 JVM:-XX:-UseSpinning 在进入操作系统线程同步代码之前在 Java 监视器上启用 naive spin。 (仅与 1.4.2 和 5.0 相关。)[1.4.2,多处理器 Windows 平台:true]
猜你喜欢
  • 1970-01-01
  • 2021-02-09
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-10
相关资源
最近更新 更多