Witaj Amigo!

I jeszcze parę szczegółów. Czyli praktyczna rada.

Załóżmy, że masz metodę, która czeka na coś i zasypia, dopóki warunek nie zostanie spełniony.

Jeśli kolekcja jest pusta, poczekaj
public synchronized Runnable getJob()
{
 if (jobs.size()==0)
  this.wait();

 return jobs.remove(0);
}

Dokumentacja Java zdecydowanie zaleca wywoływanie metody wait w pętli:

Jeśli kolekcja jest pusta, poczekaj
public synchronized Runnable getJob()
{
 while (jobs.size()==0)
  this.wait();

 return jobs.remove(0);
}

Dlaczego jest to konieczne. Faktem jest, że takich wątków do spania może być dwa tuziny. Obudzili wszystkich i tylko jeden może podjąć się zadania. Wątek został obudzony - ale to nie znaczy, że warunek został spełniony!

Z grubsza mówiąc, mogą wystąpić „fałszywe pobudki”. Dobry programista powinien wziąć to pod uwagę.

- Jasne. Czy nie łatwiej jest wtedy użyć po prostu powiadomić?

Co jeśli na liście jest więcej niż jedno zadanie? Notify jest zwykle zalecane ze względu na optymalizację. We wszystkich innych przypadkach zaleca się użycie metody notifyAll.

- OK.

"Ale to nie wszystko. Po pierwsze może zaistnieć sytuacja, gdy ktoś odziedziczył po Twojej klasie, dodał tam swoje metody, a także użyje wait/notifyAll. Te. może dojść do sytuacji, w której niezależne czekaj / powiadamiajWszystkie pary wiszą na jednym obiekcie, które nie wiedzą o sobie. Co zatem należy zrobić?

- Zawsze wywołuj wait w pętli i sprawdzaj, czy warunek wyjścia z pętli rzeczywiście został spełniony!

- Prawidłowy. Aby było dla ciebie całkowicie jasne, że nie ma od tego ucieczki, wielu programistów zwraca uwagę, że czasami wątki budzą się same. Wątki, które gwarantują, że nikt nie może obudzić się przez przypadek. Wydaje się, że jest to poboczny proces optymalizacji/przyspieszania kodu w działającej maszynie Java.

- Wow. Zrozumiałe, bez cyklu przed czekaniem gdziekolwiek.