Разлика между чакане и сън в Java

1. Общ преглед

В тази кратка статия ще разгледаме стандартните методи sleep () и wait () в основната Java и ще разберем разликите и приликите между тях.

2. Общи разлики между чакане и сън

Просто казано, wait () е метод на екземпляр, който се използва за синхронизация на нишки.

Той може да бъде извикан за всеки обект, както е дефиниран точно в java.lang.Object, но може да бъде извикан само от синхронизиран блок . Освобождава ключалката на обекта, за да може друга нишка да скочи и да придобие ключалка.

От друга страна, Thread.sleep () е статичен метод, който може да бъде извикан от всеки контекст. Thread.sleep () прави пауза на текущата нишка и не освобождава никакви ключалки.

Ето един много опростен първоначален поглед на тези два основни 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 секунда

Обектът [[имейл защитен] “се събужда след изчакване за 1 секунда

3. Събуждане Изчакай и заспи

Когато използваме метода sleep () , нишката започва след определен интервал от време, освен ако не е прекъсната.

За wait () процесът на събуждане е малко по-сложен. Можем да събудим нишката, като извикаме методите notify () или notifyAll () на монитора, който се чака.

Използвайте notifyAll () вместо notify (), когато искате да събудите всички нишки, които са в състояние на изчакване. Подобно на самия метод wait () , notify () и notifyAll () трябва да бъдат извикани от синхронизирания контекст.

Например, ето как можете да изчакате :

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); }

И тогава, ето как друга нишка може след това да събуди чакащата нишка - чрез извикване на notify () на монитора :

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

Изпълнението на този пример ще доведе до следния изход:

Изчаква се ThreadB да завърши ...

ThreadB завърши. Сумата от тази нишка е: 704982704

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

Това е кратък пример за семантиката на чакане и сън в Java.

По принцип трябва да използваме sleep () за контролиране на времето за изпълнение на една нишка и да изчакаме () за синхронизация с няколко нишки. Естествено има още много неща за изследване - след като добре разберете основите.

Както винаги, можете да разгледате примерите, предоставени в тази статия, в GitHub.