今天我面试了一名候选人,问了一个相当常见和基础的问题,即 Thread.sleep()
和 Object.wait()
之间的区别。我希望他像这里提到的那样回答,但他说这些方法基本上是一样的,很可能 Thread.sleep
在内部使用了 Object.wait()
,但 sleep
本身不需要外部锁。这不是完全正确的答案,因为在JDK 1.6中,该方法具有以下签名。
public static native void sleep(long millis) throws InterruptedException;
但我的第二个想法是这并不荒谬。可以使用定时等待来达到同样的效果。看一下以下代码片段:
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)
这样的调用很有用。根据这篇文章:
因此,这具有清除当前线程量子并将其放置在其优先级级别的队列末尾的特殊效果。换句话说,在下一个给予 CPU 时间的线程是已运行的相同优先级 (和那些更高优先级的线程) 之前,所有可运行的线程都会得到一个机会。
synchronized
块会给出不必要的开销。
你知道不使用定时等待在 Thread.sleep()
实现中的其他原因吗?