【问题标题】:Thread.join(millisecond) is not accuracy in java?Thread.join(millisecond) 在 java 中不准确?
【发布时间】:2013-12-06 14:52:06
【问题描述】:

在java中大家都知道,Thread.join(long millis)的意思是“最多等待毫秒毫秒让这个线程死掉”,但是我发现毫秒不是很准确,请看下面的代码:

public class MyThreadTest {
public void invokeTest() {
    long executionTimeLimit = 10;
    Runner rn = new Runner();
    rn.start();
    try {
        long time = System.currentTimeMillis();
        rn.join(executionTimeLimit);
        long l1 = (System.currentTimeMillis() - time);
        System.out.println("execution_time_limit="+executionTimeLimit+" the invoke method time is "+l1+" millisecond");
    } catch (Exception e) {
        //e.printStackTrace();
    }
}
public static void main(String args[]) {
    MyThreadTest mtt = new MyThreadTest();
    mtt.invokeTest();
}
private final class Runner extends Thread {
    public void run()
    {
        //to make the program a bit longer
        int size = 3000;
        String[][] bb = new String[size][size];
        for(int i=0;i<size;i++) 
            for(int j=0;j<size;j++) {
                bb[i][j] = "bbbbbbbbbbb";
        }

    }
}
}

运行多次后输出的日志不一样:

"execution_time_limit=10 调用方法时间为11毫秒" "execution_time_limit=10 调用方法时间为 32 毫秒" "execution_time_limit=10 调用方法时间为34毫秒"

为什么会这样?

【问题讨论】:

  • 在测量持续时间时,定时器/时钟精度存在一般问题。看看这里:stackoverflow.com/questions/351565/…
  • 这甚至不是 Java 问题。如果您想要高精度的线程调度,您很可能最终会使用自旋锁定。

标签: java multithreading


【解决方案1】:

当您等待(n)或睡眠(n)并且它没有被中断或通知()时,它会等待至少给定的时间。在 join(n) 中,两者都是可能的。它会在线程通知/结束时提前唤醒,但之后可以在任何时间唤醒。

在线程何时可以唤醒和何时唤醒之间的差异是如此之大,有一些工具可以监控这些事情。 jHiccup 是最好的之一。

线程何时唤醒取决于onload,也取决于OS。这可能导致线程在它们应该唤醒很久之后。 MacOS 最近的一个问题是关于空闲系统延迟最多 10 秒的延迟。

这是 Java 无法控制的,它取决于您的操作系统。

顺便说一句,如果您查看微秒级别的抖动,您会看到更多丰富多彩的变化/抖动/过程中断。

Micro jitter, busy waiting and binding CPUs

【讨论】:

  • at least the time given, but it could wake early 你是说最多
  • @SotiriosDelimanolis join() 基于 wait()/notify()。如果没有调用 notify,wait 会在超时后唤醒。即当操作系统接受它时。
  • 我的评论只是为了改变你说它的方式。你不能说至少,但可以说它可以早点醒来。如果它是最小的,那么在它之前就什么都没有了。可能会混淆某人(绝对不是我:p)。
【解决方案2】:

当我们处理线程时,我们永远无法保证时间的准确性,因为等待、加入、睡眠等操作也依赖于系统资源的可用性。

查看Oracle教程http://docs.oracle.com/javase/tutorial/essential/concurrency/join.html

【讨论】:

    【解决方案3】:

    doxygen 只是让您感到困惑,因为它说“等待 最多 毫秒让该线程死亡”。

    join() 函数只允许调用线程“等待一段时间”,而不是永远卡住。当 join() 函数返回时,您调用它的线程可能仍在运行(即它没有“加入”)。在这种情况下,join() 将等待 至少 毫秒毫秒,然后该线程没有完成并且 join() 放弃了。另一方面,如果线程 join() 已被调用并实际完成,则 join() 将等待不到几毫秒。

    还请记住,除非您的 JVM 在实时操作系统上运行(并且这些线程具有特定的优先级),否则其他进程/线程可以被调度,从而导致 join() 返回延迟更长的时间(这种情况发生了当你有 34 毫秒而不是 11 毫秒时)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-26
      • 2014-04-29
      • 2019-05-09
      • 1970-01-01
      • 2013-09-02
      • 1970-01-01
      • 1970-01-01
      • 2012-03-20
      相关资源
      最近更新 更多