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

Java

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

В этой статье мы обсудим разницу между методами wait() и sleep() в java. И обсудите, как использовать эти два метода.

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

wait() — это нативный метод, определенный в Object:

public final native void wait(long timeout) throws InterruptedException;

Таким образом, каждый экземпляр класса может вызывать этот метод. wait() можно вызывать только в синхронизированном блоке. Он снимет блокировку объекта при синхронизации.

sleep() — это нативный метод статического класса, определенный в Thread:

public static native void sleep(long millis) throws InterruptedException;

Так что Thread.sleep() можно вызывать при любых обстоятельствах. Thread.sleep() приостановит текущий поток и не освободит ресурсы блокировки.

Давайте сначала рассмотрим простое использование ожидания:

@Slf4j
public class WaitUsage {

    private static Object LOCK = new Object();

    public static void WaitExample() throws InterruptedException {
        synchronized (LOCK) {
            LOCK.wait(1000);
            log.info("Object '" + LOCK + "' is woken after" +
                    " waiting for 1 second");
        }
    }
}

Посмотрите еще раз на использование сна:

@Slf4j
public class SleepUsage {

    public static void sleepExample() throws InterruptedException {
        Thread.sleep(1000);
        log.info(
                "Thread '" + Thread.currentThread().getName() +
                        "' is woken after sleeping for 1 second");
    }
}

Просыпайся, жди и спи

Метод sleep() имеет время ожидания, по истечении которого поток автоматически пробуждается. Или его можно прервать, вызвав метод interrupt().

Напротив, пробуждение ожидания более сложное: нам нужно вызвать методы notify() и notifyAll(), чтобы разбудить потоки, ожидающие определенного объекта ожидания.

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

подождите, notity обычно используется в ситуациях производителя и потребителя, давайте посмотрим, как его использовать:

@Slf4j
public class WaitNotifyUsage {

    private int count =0;

    public void produceMessage() throws InterruptedException {

        while(true) {
            synchronized (this) {
                while (count == 5) {
                    log.info("count == 5 , wait ....");
                    wait();
                }
                count++;
                log.info("produce count {}", count);
                notify();
            }
        }
    }

    public void consumeMessage() throws InterruptedException {

        while (true) {
            synchronized (this) {
                while (count == 0) {
                    log.info("count == 0, wait ...");
                    wait();
                }
                log.info("consume count {}", count);
                count--;
                notify();
            }
        }
    }
}

Посмотрите, как звонить:

   @Test
    public void testWaitNotifyUsage() throws InterruptedException{
        WaitNotifyUsage waitNotifyUsage=new WaitNotifyUsage();

        ExecutorService executorService=Executors.newFixedThreadPool(4);
        executorService.submit(()-> {
            try {
                waitNotifyUsage.produceMessage();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        executorService.submit(()-> {
            try {
                waitNotifyUsage.consumeMessage();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread.sleep(50000);
    }

Примеры этой статьи могут относиться кGitHub.com/Dadean2009/приходите…

Дополнительные руководства см.блог флайдина