Witaj Amigo!

Cześć Risza!

„Zapoznam Cię z metodami wait , powiadamiaj , powiadamiaj Wszystkie klasy Object.

Dzisiaj dopiero się z nimi zapoznamy, ale potem wrócimy ponownie i już przeznaczymy na to więcej czasu.

- Cienki.

— Metody te zostały wynalezione jako część mechanizmu synchronizacji wątków.

Przypomnę, że Java ma wbudowany mechanizm zarządzania dostępem do współdzielonych zasobów (obiektów) z różnych wątków. Wątek może zadeklarować, że jakiś obiekt jest zajęty, a inne wątki będą zmuszone czekać, aż zajęty obiekt zostanie zwolniony.

- Pamiętam, że odbywa się to za pomocą słowa kluczowego synchronized .

- Prawidłowy. Zazwyczaj ten kod wygląda mniej więcej tak:

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

Czy pamiętasz, jak to działa?

- Tak. Jeśli dwa wątki wywołają metodę print() w tym samym czasie, jeden z nich wejdzie do bloku oznaczonego jako zsynchronizowany i zablokuje monitor, więc drugi wątek będzie czekał, aż monitor będzie wolny.

- Prawidłowy. Gdy tylko wątek wejdzie do bloku oznaczonego jako zsynchronizowany, obiekt monitorujący jest oznaczony jako zajęty, a inne wątki będą musiały czekać, aż obiekt monitorujący zwolni się. Ten sam obiekt monitora może być używany w różnych częściach programu.

- Nawiasem mówiąc, dlaczego - monitor?

- Zwyczajowo nazywa się monitor obiektem przechowującym stan zajęty/wolny.

W tym miejscu do gry wchodzą metody oczekiwania i powiadamiania .

Właściwie istnieją tylko dwie metody jako takie. Reszta to tylko modyfikacje tych metod.

Teraz zastanówmy się, czym jest metoda oczekiwania i dlaczego jest potrzebna.

Czasami w programie może dojść do takiej sytuacji, że wątek wszedł do zsynchronizowanego bloku kodu, zablokował monitor i nie może dalej pracować, bo. nadal brakuje niektórych danych: na przykład plik, który powinien przetworzyć, nie został jeszcze załadowany lub coś w tym stylu.

Możemy po prostu poczekać, aż plik się pobierze. Możesz po prostu sprawdzić w pętli - jeśli plik jeszcze się nie pobrał - przespać się np. na sekundę i sprawdzić ponownie itp.

Tak:

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

Ale w naszym przypadku takie oczekiwanie jest zbyt drogie. Ponieważ Ponieważ nasz wątek zablokował monitor, inne wątki też są zmuszone czekać, chociaż ich dane do pracy mogą być już gotowe.

Aby rozwiązać ten problem, wynaleziono metodę wait () . Wywołanie tej metody powoduje, że wątek zwalnia monitor i „wstrzymuje”.

Metodę wait można wywołać na obiekcie monitora i tylko wtedy, gdy ten monitor jest zajęty — tj. wewnątrz zsynchronizowanego bloku . Powoduje to tymczasowe zatrzymanie wątku i zwolnienie monitora, aby inne wątki mogły z niego korzystać.

Często zdarzają się sytuacje, gdy wątek wszedł do zsynchronizowanego bloku , wywołał tam czekaj i zwolnił monitor.

Następnie wszedł drugi wątek i również się zatrzymał, potem trzeci i tak dalej.

- A jak wątek zostanie usunięty z pauzy?

- Jest na to druga metoda - powiadomić.

MetodyNotify / NotifyAll można wywoływać na obiekcie monitora i tylko wtedy, gdy ten monitor jest zajęty — tj . wewnątrz zsynchronizowanego bloku . Metoda notifyAll wznawia wstrzymanie wszystkich wątków, które zostały wstrzymane przez dany obiekt monitora.

Metoda notify „odmraża” jeden losowy wątek, metoda notifyAll – wszystkie „zamrożone” wątki danego monitora.

— Bardzo interesujące, dzięki Risha.

- Cieszę się, że ci się podoba, Amigo!

Istnieje więcej modyfikacji metody wait ():

Metoda oczekiwania(). Wyjaśnienie
void wait(long timeout)
Wątek „zawiesza się”, ale po upływie określonej liczby milisekund automatycznie „odblokowuje się”.
void wait(long timeout, int nanos)
Wątek „zawiesza się”, ale po upływie określonej liczby milisekund i nanosekund automatycznie „odmraża”.

To jest, jak mówią, czekać z limitem czasu. Metoda działa jak zwykłe oczekiwanie, ale jeśli minął określony czas i nikt nie przerwał pauzy wątku, aktywuje się sama.