【问题标题】:Thread sleeps for too long线程休眠时间过长
【发布时间】:2017-06-27 02:58:42
【问题描述】:

我写了一个简单的程序,发现我的线程太快了,无法运行 JVisualVM,标记我想要监控的应用程序,插入并查看线程。然后我让他们睡觉。并且注意到工具现在将它们报告为仅在睡眠(或几乎仅在睡眠)。即使他们工作。这就引出了一个问题:为什么?!

    new Thread(() -> {
        while(true) {
            System.out.println("not sleeping");
            try {
                Thread.sleep(0,1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }, "not sleeping!").start();

这个线程应该休眠 1 纳秒,但看看 JVisualVM 是如何报告的:

运行 57 秒后,它报告运行时间为 5 秒,休息为睡眠 - 是错误还是我的理解有误?

不仅仅是 JVisualVM:

$ while true; do jstack 8277 | grep -A 2 not; done              [% 20:34:27]
"not sleeping!" #10 prio=5 os_prio=0 tid=0x00007f5ea82d1000 nid=0x2078 waiting on condition [0x00007f5e917c6000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)

jstack 也只是偶尔将此线程报告为 RUNNING。我期望不同的比例,所以请帮助我理解。

【问题讨论】:

  • 您不能依赖线程在您指定的确切时间内休眠。 57s 是……不过。
  • @AndyTurner 我同意。纳米技术更是如此。但我没想到比例会……嗯,颠倒了。大部分时间都在睡觉。

标签: java multithreading


【解决方案1】:

您不能期望睡眠时间只有 1 纳秒。当您请求睡眠时,您将执行任务切换,并且需要一些时间才能将其安排回来,特别是如果您有其他进程/线程。因此,如果线程的工作负载非常低,那么它可能最终大部分时间都在休眠。

您的睡眠时间也可能在某个层被四舍五入到系统时间粒度的倍数。至少在某些 Java 实现中,nanos 参数 is mostly ignored

【讨论】:

  • 我要求 1 ns 以使其最小化。我从没想过 1ns,因为几乎所有具有 nanos 状态的 Java 方法在文档中都依赖于系统。不过,对于其他想要检查是否如此的人,请查找上下文切换的数量(来自 /proc 的 pidstat 或 cat 线程状态)。感谢源链接和答案!增加工作负载(随机 n 的斐波那契)使线程大部分可运行。
猜你喜欢
  • 1970-01-01
  • 2021-07-08
  • 1970-01-01
  • 2010-10-06
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多