In realtà, le scia spurie in Java si verificano?

Vedendo varie domande relative al blocco e (quasi) trovando sempre il termine “loop a causa di scatti spuri” 1 mi chiedo, qualcuno ha mai provato un tale tipo di wakeup (presupponendo un ambiente hardware / software decente per esempio)?

So che il termine “spurio” significa nessuna ragione apparente, ma quali possono essere le ragioni di questo tipo di evento?

( 1 Nota: non sto mettendo in dubbio la pratica del ciclo.)

Modifica: una domanda di supporto (per coloro a cui piacciono i campioni di codice):

Se ho il seguente programma, e lo eseguo:

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

Cosa posso fare per risvegliarlo atteso spurio senza aspettare per sempre un evento casuale?

L’ articolo di Wikipedia su wakeups spurie ha questo bocconcino:

La funzione pthread_cond_wait() in Linux è implementata usando la chiamata di sistema futex . Ogni chiamata al sistema di blocco su Linux ritorna bruscamente con EINTR quando il processo riceve un segnale. … pthread_cond_wait() non può riavviare l’attesa perché potrebbe perdere una vera sveglia nel poco tempo futex al di fuori della chiamata di sistema futex . Questa condizione di gara può essere evitata solo dal chiamante che verifica un invariante. Un segnale POSIX genererà quindi una sveglia spuria.

Riepilogo : se viene segnalato un processo Linux, i suoi thread in attesa godranno di un bel risveglio spurio caldo.

Lo compro. È una pillola più facile da inghiottire rispetto alla ragione tipicamente vaga “è per le prestazioni” spesso data.

Ho un sistema di produzione che mostra questo comportamento. Un thread attende un segnale che c’è un messaggio nella coda. Nei periodi di punta, fino al 20% dei wakeup sono spuri (cioè quando si sveglia non c’è nulla in coda). Questo thread è l’unico consumatore dei messaggi. Funziona con un box Linux SLES-10 da 8 processori ed è realizzato con GCC 4.1.2. I messaggi provengono da una fonte esterna e vengono elaborati in modo asincrono perché ci sono problemi se il mio sistema non li legge abbastanza velocemente.

Per rispondere alla domanda nel titolo – Sì! succede. Anche se l’ articolo Wiki menziona un bel po ‘di wake up spuri, una bella spiegazione per lo stesso che ho trovato è la seguente:

Basti pensare che … come qualsiasi codice, lo scheduler dei thread potrebbe subire un blackout temporaneo a causa di qualcosa di anomalo che accade nell’hardware / software sottostante. Naturalmente, è necessario fare attenzione affinché ciò accada il più raramente ansible, ma poiché non esiste software affidabile al 100%, è ragionevole presumere che ciò possa accadere e occuparsi del ripristino agevole nel caso in cui lo scheduler lo rilevasse (ad es. osservando i battiti del cuore mancanti).

Ora, come potrebbe recuperare lo scheduler, tenendo conto che durante il blackout potrebbero mancare alcuni segnali destinati a notificare thread in attesa? Se lo scheduler non fa nulla, le discussioni “sfortunate” si bloccheranno, aspettando per sempre – per evitare ciò, lo scheduler semplicemente invierà un segnale a tutti i thread in attesa.

Ciò rende necessario stabilire un “contratto” che il thread in attesa possa essere notificato senza una ragione. Per essere precisi, ci sarebbe un motivo – blackout dello scheduler – ma poiché thread è progettato (per una buona ragione) per essere ignaro dei dettagli di implementazione interna dello scheduler, questo motivo è probabilmente meglio presentare come “spurio”.

Stavo leggendo questa risposta da Source e l’ho trovato abbastanza ragionevole. Leggi anche

Sveglie spurie in Java e come evitarli .

Solo per aggiungere questo. Sì, succede e ho passato tre giorni a cercare la causa di un problema multi-thread su un computer a 24 core (JDK 6). 4 di 10 esecuzioni hanno sperimentato questo senza alcun modello. Questo non è mai successo su 2 core o 8 core.

Ha studiato materiale online e questo non è un problema Java, ma un comportamento generale raro ma atteso.

Cameron Purdy ha scritto un post sul blog un po ‘indietro sul fatto di essere stato colpito dal problema di sveglia spuria. Quindi sì, succede

Immagino che sia nelle specifiche (come possibilità) a causa delle limitazioni di alcune piattaforms su cui viene distribuito Java? anche se potrei sbagliarmi!

https://stackoverflow.com/a/1461956/14731 contiene un’eccellente spiegazione del motivo per cui è necessario proteggersi da svegli spuri anche se il sistema operativo sottostante non li triggers. È interessante notare che questa spiegazione si applica a più linguaggi di programmazione, incluso Java.