【发布时间】:2017-03-01 23:54:00
【问题描述】:
在 Java 中,有两种访问时间的方式,System.currentTimeMillis 和 System.nanoTime。第一个类似于挂钟,可以根据闰秒改变时间,其他操作系统会导致时间改变。因此,测量持续时间更适合使用nanoTime,它更准确且通常更精确。
考虑到这一点,为什么Thread.join() 使用 currentTimeMillis 而不是 nanoTime?
有问题的代码是:
public final synchronized void join(long millis) throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
【问题讨论】:
-
因为 caller(s) 期望它像“挂钟”一样超时。
-
因为
join()是@since 1.0 而nanoTime()不是,所以改变行为是不好的做法。 -
将容易出错的行为更改为不易出错的行为是有效的。无论何时添加 join(),都可以在任何版本中重新实现。
-
@eliott 真的吗?如果您编写 wait(1h) 您希望代码每年立即返回一次吗?老实说,这是令人讨厌的行为(并且与“等待一个小时”的口语意思背道而驰),但这就是它的指定方式,而且由于问题很少出现,因此在实践中并不是一个大问题。
标签: java multithreading