Czy fałszywe przebudzenia w Javie rzeczywiście się zdarzają?

Widząc różne pytania związane z blokowaniem i (prawie) zawsze znajdując "pętlę z powodu fałszywych przebudzeń" 1 ciekawe, czy ktoś doświadczył takiego przebudzenia (zakładając na przykład porządne środowisko sprzętowe/programowe)?

Wiem, że termin "fałszywy" oznacza brak wyraźnego powodu, ale jakie mogą być przyczyny tego rodzaju zdarzenia?

(1 uwaga: nie kwestionuję praktyki zapętlania.)

Edit: pytanie pomocnicze (dla ci, którzy lubią próbki kodu):

Jeśli mam następujący program i uruchamiam go:

public class Spurious {
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        Condition cond = lock.newCondition();
        lock.lock();
        try {
            try {
                cond.await();
                System.out.println("Spurious wakeup!");
            } catch (InterruptedException ex) {
                System.out.println("Just a regular interrupt.");
            }
        } finally {
            lock.unlock();
        }
    }
}

Co mogę zrobić, aby obudzić to await nie czekając wiecznie na losowe Zdarzenie?

Author: Flow, 2009-06-26

6 answers

Artykuł na Wikipedii o fałszywych wakeupach ma taką ciekawostkę:

Funkcja pthread_cond_wait() w Linuksie jest zaimplementowana przy użyciu wywołania systemowego futex. Każde blokujące wywołanie systemowe na Linuksie powraca nagle z EINTR, gdy proces otrzyma sygnał. ... pthread_cond_wait() nie można ponownie uruchomić oczekiwania, ponieważ może przegapić prawdziwe przebudzenie w krótkim czasie było poza wywołaniem systemowym futex. Ten stan rasy można uniknąć tylko przez sprawdzanie dzwoniącego dla niezmiennika. Sygnał POSIX będzie dlatego generują fałszywy przebudzenie.

Podsumowanie: jeśli proces Linuksowy jest sygnalizowany, jego oczekujące wątki będą cieszyć się przyjemnym, gorącym fałszywym przebudzeniem .

Kupuję. Jest to łatwiejsza pigułka do połknięcia niż zwykle niejasne" to dla wydajności " powód często podane.
 185
Author: John Kugelman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-27 00:28:52

Mam system produkcyjny, który wykazuje takie zachowanie. Wątek czeka na sygnał, że w kolejce jest wiadomość. W ruchliwych okresach do 20% przebudzeń jest fałszywych(tzn. gdy się obudzi, nie ma nic w kolejce). Ten wątek jest jedynym konsumentem wiadomości. Działa na 8-procesorowym systemie Linux SLES-10 i jest zbudowany z GCC 4.1.2. Wiadomości pochodzą z zewnętrznego źródła i są przetwarzane asynchronicznie, ponieważ występują problemy, jeśli mój system nie odczytuje ich szybko wystarczy.

 20
Author: Mr.Dirty.Birdy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-29 00:43:29

Aby odpowiedzieć na pytanie w titile - tak!To się zdarza.Chociaż artykuł Wiki wspomina dużo o fałszywych przebudzeniach ładne wyjaśnienie tego samego, na które natknąłem się jest następujące -

Pomyśl o tym... jak każdy kod, harmonogram wątków może doświadczyć tymczasowego zaniku zasilania z powodu czegoś nienormalnego, co dzieje się w podstawowym sprzęcie / oprogramowaniu. Oczywiście należy zadbać o to, aby stało się to tak rzadko, jak to możliwe, ale ponieważ nie ma takiego rzecz w 100% solidne oprogramowanie jest uzasadnione, aby założyć, że może się to zdarzyć i dbać o graceful odzyskiwania w przypadku, gdy scheduler wykryje to (np obserwując brakujące uderzenia serca).

Teraz, jak scheduler może odzyskać, biorąc pod uwagę, że podczas blackoutu może przegapić niektóre sygnały mające zawiadomić oczekujące wątki? Jeśli scheduler nic nie zrobi, wspomniane" pechowe " wątki będą po prostu wisieć, czekając wiecznie - aby tego uniknąć, scheduler po prostu wyśle sygnał do wszystkich oczekujących nici.

To sprawia, że konieczne jest ustanowienie "umowy", że wątek oczekujący może być zgłoszony bez podania przyczyny. Aby być precyzyjnym, nie byłoby powodu-scheduler blackout - ale ponieważ wątek jest zaprojektowany (nie bez powodu), aby być nieświadomym szczegółów wewnętrznej implementacji scheduler, powód ten prawdopodobnie lepiej przedstawić jako "fałszywy".

Czytałem tę odpowiedź ze źródła i uznałem ją za wystarczająco rozsądną. Przeczytaj również

Sfałszowane przebudzenia w Javie i jak ich unikać.

 12
Author: Aniket Thakur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-12 07:31:17

Tylko dodać to. Tak się dzieje i spędziłem trzy dni szukając przyczyny problemu wielowątkowego na maszynie 24-rdzeniowej (JDK 6). 4 z 10 egzekucji doświadczyło tego bez żadnego wzoru. To nigdy nie zdarzyło się na 2 rdzeniach lub 8 rdzeniach.

Przestudiowałem niektóre materiały online i nie jest to problem Javy, ale ogólne rzadkie, ale oczekiwane zachowanie.

 8
Author: ReneS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-05 12:42:45

Cameron Purdy napisał blog post jakiś czas temu o uderzeniu przez fałszywy problem przebudzenia. Więc tak, zdarza się

Zgaduję, że jest w specyfikacji (jako możliwość) z powodu ograniczeń niektórych platform, na których Java jest wdrażana? chociaż mogę się mylić!

 8
Author: oxbow_lakes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-10 14:30:15

Https://stackoverflow.com/a/1461956/14731 zawiera doskonałe wyjaśnienie, dlaczego musisz chronić się przed fałszywymi przebudzeniami, nawet jeśli podstawowy system operacyjny ich nie uruchamia. Warto zauważyć, że to wyjaśnienie ma zastosowanie w wielu językach programowania, w tym w Javie.

 0
Author: Gili,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-03 17:52:53