Разница между ожиданием и сном в Java

Разница между ожиданием и сном в Java

1. обзор

В этой короткой статье мы рассмотрим стандартные методыsleep() иwait() в ядре Java и поймем различия и сходства между ними.

2. Общие различия междуWait иSleep

Проще говоря,wait() is an instance method that’s used for thread synchronization.

Его можно вызвать для любого объекта, так как он определен прямо наjava.lang.Object,, но может и наonly be called from a synchronized block. Он снимает блокировку объекта, так что другой поток может подключиться и получить блокировку.

С другой стороны,Thread.sleep() - это статический метод, который можно вызывать из любого контекста. Thread.sleep() pauses the current thread and does not release any locks.

Вот очень упрощенный начальный взгляд на эти два основных 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");
    }
}

Запуск этого примера приведет к следующему выводу:

Поток "main" просыпается после сна в течение 1 секунды Объект «[email protected]» просыпается после ожидания в течение 1 секунды

3. ПробуждениеWait иSleep

Когда мы используем методsleep(), поток запускается через заданный интервал времени, если он не прерывается.

Дляwait() процесс пробуждения немного сложнее. Мы можем разбудить поток, вызвав методыnotify() илиnotifyAll() на ожидаемом мониторе.

ИспользуйтеnotifyAll() вместоnotify(), если вы хотите разбудить все потоки, находящиеся в состоянии ожидания. Как и сам методwait(),notify() иnotifyAll() должны вызываться из синхронизированного контекста.

Например, вот как можно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);
}

А затем вот как другой поток может затемwake up the waiting thread – by calling notify() on the monitor:

int sum;

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

Запуск этого примера приведет к следующему выводу:

Waiting for ThreadB to complete…ThreadB has completed. Суммаfrom that thread is: 704982704

4. Заключение

Это краткое руководство по семантикеwait иsleep в Java.

В общем, мы должны использоватьsleep() для управления временем выполнения одного потока иwait() для многопоточной синхронизации. Естественно, есть еще много чего исследовать - после хорошего понимания основ.

Как всегда, вы можете ознакомиться с примерами из этой статьиover on GitHub.