„Здрасти, Амиго!“

„Здрасти, Риши!“

„Ще ви запозная с методите wait , notify и notifyAll на класа Object .“

„Днес просто ще се запознаем с тях, но ще се върнем по-късно и ще отделим повече време на това.“

"Добре."

„Тези методи са измислени като част от механизма за синхронизиране на нишките.“

„Позволете ми да ви напомня, че Java има вграден механизъм за контролиране на достъпа до споделени ресурси (обекти) от различни нишки. Една нишка може да декларира, че даден обект е зает, а други нишки ще трябва да изчакат, докато заетият обект бъде освободен. "

„Спомням си. Вие правите това, като използвате синхронизираната ключова дума.“

„Точно така. Обикновено codeът би изглеждал така:“

public void print()
{
 Object monitor = getMonitor();
 synchronized(monitor)
 {
  System.out.println("text");
 }
}

— Помниш ли How става това?

"Да. Ако две нишки едновременно извикат метода print(), едната от тях ще влезе в блока, обозначен като синхронизиран, и ще заключи монитора, което го прави така, че втората нишка ще изчака, докато мониторът бъде освободен."

„Точно. След като нишка влезе в блока, означен като синхронизиран, обектът на монитора се маркира като зает и другите нишки ще бъдат принудени да чакат обектът на монитор да бъде освободен. Един и същ обект на монитор може да се използва в различни части на програмата. "

„Между другото, защо избрахте името монитор?“

„Монитор е това, което обикновено наричате обект, който съхранява състоянието на заето or свободното.“

„И тук влизат в действие методите за изчакване и уведомяване .“

"Всъщност това са единствените два метода. Другите са само адаптации на тези методи."

„Сега нека се замислим Howво представлява методът на изчакване и защо имаме нужда от него.

„Понякога има ситуации в програма, при които нишката влиза в блок от синхронизиран code и заключва монитора, но не може да продължи, защото липсват някои данни. Например, файл, който трябва да обработи, не е завършил изтеглянето or нещо такова."

„Можем просто да изчакаме файлът да бъде изтеглен. Можете просто да го проверите с помощта на цикъл. Ако файлът все още не е изтеглен, тогава спете за секунда or повече и проверете отново, докато не бъде изтеглен.“

"Нещо като това:"

while(!file.isDownloaded())
{
 Thread.sleep(1000);
}
processFile(file);

„Но в нашия случай този тип чакане е твърде скъп. Тъй като нашата нишка заключи монитора, други нишки също са принудени да чакат, въпреки че може вече да разполагат с данните, от които се нуждаят.“

„ Методът wait() е изобретен, за да реши този проблем. Този метод кара нишката да освободи монитора и след това «преустановява» нишката.

"Можете да извикате метод за изчакване на обект на монитор само когато мониторът е зает, т.е. само вътре в синхронизиран блок. Когато това се случи, нишката временно спира да работи и мониторът се освобождава, така че други нишки да могат да я използват."

„Често има случаи, когато нишка ще влезе в синхронизиран блок и ще извика изчакване, като по този начин ще освободи монитора.“

„Тогава ще влезе втора нишка и ще бъде спряна, след това трета и така нататък.“

„И How се възобновява една нишка?“

„За това има втори метод: уведомяване.“

„Можете да извиквате методите notify / notifyAll на обект на монитор само когато мониторът е зает, т.е. само вътре в синхронизиран блок. Методът notifyAll събужда всички нишки, които чакат на този обект на монитор.“

„ Методът notify „отмразява“ една произволна нишка, но методът notifyAll отмразява всички „замразени“ нишки на този монитор.“

„Много интересно. Благодаря ти, Риши.“

„Има и адаптации на метода wait():“

метод wait(). Обяснение
void wait(long timeout)
Нишката «замръзва», но автоматично се «размразява» след изчакване на броя мorсекунди, предадени на метода като аргумент.
void wait(long timeout, int nanos)
Нишката «замръзва», но автоматично се «размразява» след изчакване на броя наносекунди, предадени на метода като аргумент.

„Ние също наричаме това изчакване с изчакване. Методът работи като нормално изчакване, но ако определеното време е изтекло и нишката не е била събудена, тя се събужда сама.“