2012-03-21 15 views
5

Questa classe è sicura per thread?AtomicInteger vs getter/setter sincronizzati

È possibile visualizzare valori incoerenti? Diciamo che inizialmente il valore di a è 80. Thread 1 chiama setA(100) ed inserisce la funzione ma non ha ancora chiamato a.set(100) e Thread 2 chiama contemporaneamente getA(). È possibile che Thread 2 veda 80?

So che la sincronizzazione garantirà thread 2 ne vede 100, ma non è sicuro con AtomicInteger.

risposta

9

Questa classe è sicura per i thread?

Sì, lo è.

Il thread 1 chiama setA (100) e immette la funzione ma non ha ancora chiamato a.set (100) e Thread 2 chiama contemporaneamente getA(). È possibile che Thread 2 veda 80?

Sì. Fino a quando il codice della barriera di memoria che sincronizza il campo volatile all'interno di AtomicInteger non è completo, le condizioni della competizione possono mostrare 80 o 100.

Il thread 1 potrebbe anche immettere il metodo AtomicInteger.set ed essere prima dell'assegnazione del campo interno e ancora 80 potrebbe essere restituito con il metodo AtomicInteger.get.

Non ci sono garanzie circa quando i valori verranno aggiornati in altri thread. Ciò che è garantito è quando il get() viene completato, si ottiene il valore sincronizzato più recente e quando lo set() viene completato, tutti gli altri thread vedranno gli aggiornamenti.

Non vi è alcuna garanzia sul timing di chiamate getter e setter in thread diversi.

1

Come indicato da @Gray, esiste una possibilità per una condizione di gara qui.

Chiamare get e quindi set non è un'operazione atomica. The Atomic* classes offre un'operazione di aggiornamento condizionale atomico senza blocco, compareAndSet - è necessario utilizzare quello per la sicurezza del thread.