Difference Between Wait and Sleep in Java – Java中等待和睡眠的区别

最后修改: 2017年 4月 30日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this short article, we’ll have a look at the standard sleep() and wait() methods in core Java, and understand the differences and similarities between them.

在这篇短文中,我们将看看核心Java中的标准sleep()wait()方法,并了解它们之间的差异和相似之处。

2. General Differences Between Wait and Sleep

2.等待睡眠之间的一般区别

Simply put, wait() is an instance method that’s used for thread synchronization.

简单地说,wait()是一个用于线程同步的实例方法。

It can be called on any object, as it’s defined right on java.lang.Object, but it can only be called from a synchronized block. It releases the lock on the object so that another thread can jump in and acquire a lock.

它可以在任何对象上被调用,因为它就定义在 java.lang.Object上,但它只能在同步块中被调用。它释放了对象上的锁,这样另一个线程就可以跳入并获得锁。

On the other hand, Thread.sleep() is a static method that can be called from any context. Thread.sleep() pauses the current thread and does not release any locks.

另一方面,Thread.sleep()是一个静态方法,可以从任何上下文中调用。Thread.sleep()暂停了当前线程,并且不释放任何锁。

Here’s a very simplistic initial look at these two core APIs in action:

下面是对这两个核心API运作的一个非常简单的初步观察。

private static Object LOCK = new Object();

private static void sleepWaitExamples() 
  throws InterruptedException {
 
    Thread.sleep(1000);
    System.out.println(
      "Thread '" + Thread.currentThread().getName() +
      "' is woken after sleeping for 1 second");
 
    synchronized (LOCK) {
        LOCK.wait(1000);
        System.out.println("Object '" + LOCK + "' is woken after" +
          " waiting for 1 second");
    }
}

Running this example will produce the following output:

运行这个例子将产生以下输出。

Thread ‘main’ is woken after sleeping for 1 second
Object ‘java.lang.Object@31befd9f’ is woken after waiting for 1 second

线程’main’在睡眠1秒后被唤醒
对象’java.lang.Object@31befd9f’在等待1秒后被唤醒

3. Waking up Wait and Sleep

3.醒来后等待睡眠

When we use the sleep() method, a thread gets started after a specified time interval, unless it is interrupted.

当我们使用sleep()方法时,一个线程在指定的时间间隔后被启动,除非它被打断。

For wait(), the waking up process is a bit more complicated. We can wake the thread by calling either the notify() or notifyAll() methods on the monitor that is being waited on.

对于wait()来说,唤醒过程要复杂一些。我们可以通过调用被等待的监视器上的notify() notifyAll() 方法来唤醒线程。

Use notifyAll() instead of notify() when you want to wake all threads that are in the waiting state. Similarly to the wait() method itself, notify(), and notifyAll() have to be called from the synchronized context.

当你想唤醒所有处于等待状态的线程时,使用notifyAll()而不是notify()。与wait()方法本身类似,notify()notifyAll()必须从同步上下文中调用。

For example, here’s how you can wait:

例如,这里是你如何等待

synchronized (b) {
    while (b.sum == 0) {
        System.out.println("Waiting for ThreadB to complete...");
        b.wait();
    }

    System.out.println("ThreadB has completed. " + 
      "Sum from that thread is: " + b.sum);
}

And then, here’s how another thread can then wake up the waiting thread – by calling notify() on the monitor:

然后,这里是另一个线程如何然后唤醒等待的线程–通过调用监视器上的notify()

int sum;
 
@Override 
public void run() {
    synchronized (this) {
        int i = 0;
        while (i < 100000) {
            sum += i;
            i++; 
        }
        notify(); 
    } 
}

Running this example will produce the following output:

运行这个例子将产生以下输出。

Waiting for ThreadB to complete…
ThreadB has completed. Sum from that thread is: 704982704

等待线程B完成…
线程B已经完成。该线程的总和为:704982704

4. Conclusion

4.结论

This is a quick primer to the semantics of wait and sleep in Java.

这是对Java中waitsleep语义的快速入门。

In general, we should use sleep() for controlling execution time of one thread and wait() for multi-thread-synchronization. Naturally, there’s a lot more to explore – after understanding the basics well.

一般来说,我们应该使用sleep()来控制一个线程的执行时间,使用wait()来实现多线程的同步化。当然,在很好地理解了这些基础知识之后,还有很多东西需要探索。

As always, you can check out the examples provided in this article over on GitHub.

一如既往,你可以在GitHub上查看本文提供的例子