【发布时间】:2012-02-22 18:03:26
【问题描述】:
今天我参加了一次面试,我问了候选人关于Thread.sleep() 和Object.wait() 之间区别的非常普通和基本的问题。我希望他回答like this之类的问题,但他说这些方法基本上是一样的,很可能Thread.sleep在里面使用Object.wait(),但sleep本身不需要外部锁。这不是一个完全正确的答案,因为在 JDK 1.6 中,此方法具有以下签名。
public static native void sleep(long millis) throws InterruptedException;
但我的第二个想法是这并不荒谬。可以使用定时等待来达到相同的效果。看看下面的代码sn -p:
public class Thread implements Runnable {
private final Object sleepLock = new Object();
// other implementation details are skipped
public static void sleep(long millis) throws InterruptedException {
synchronized (getCurrentThread().sleepLock){
getCurrentThread().sleepLock.wait(millis);
}
}
在这种情况下,sleepLock 是一个对象,专门用于sleep 方法中的同步块。我假设 Sun/Oracle 工程师都知道奥卡姆剃刀,所以sleep 有目的有本机实现,所以我的问题是为什么它使用本机调用。
我想出的唯一想法是假设有人可能会发现有用的调用,例如Thread.sleep(0)。根据this article:进行调度管理是有意义的
这具有清除当前线程的量程并将其置于队列末尾以获得其优先级的特殊效果。换句话说,所有具有相同优先级(以及更高优先级)的可运行线程将有机会在产生的线程下一次给定 CPU 时间之前运行。
所以synchronized 块会产生不必要的开销。
您知道在Thread.sleep() 实现中不使用定时等待的其他原因吗?
【问题讨论】:
-
wait(millis) 可以虚假(早)醒来,而 sleep 除非被中断,否则不会早醒。
-
在调用 sleep() 期间是否检查了中断标志以便抛出异常并返回?或者不知何故,这个调用也转到了调度程序,然后调度程序知道结束线程的睡眠?
-
我会更关心他们是否知道如何正确处理 InterruptedException。
标签: java multithreading sleep wait