Assumendo:Se si dispone di un solo thread di scrittura, è mai necessario un concorrente speciale?
- C'è solo un filo specifico che mai imposta un determinato campo di riferimento (non un lungo o doppia, quindi scrive ad esso sono atomico)
- Ci sono un certo numero di fili che potrebbero letto che stesso campo
- letture leggermente stantio sono accettabili (fino a pochi secondi)
In questo scenario, è necessario fare AtomicReference volatile o o qualcosa di simile?
This article stati:
barriere di memoria non sono necessari se aderire rigorosamente al principio solo scrittore.
Il che sembra suggerire che nel caso che sto descrivendo, davvero non è necessario fare nulla di speciale.
Quindi, ecco un test mi sono imbattuto con risultati curiosi:
import org.junit.Test;
public class ThreadTest {
int onlyWrittenByMain = 0;
int onlyWrittenByThread = 0;
@Test
public void testThread() throws InterruptedException {
Thread newThread = new Thread(new Runnable() {
@Override
public void run() {
do {
onlyWrittenByThread++;
} while (onlyWrittenByMain < 10 || onlyWrittenByThread < 10);
System.out.println("thread done");
}
});
newThread.start();
do {
onlyWrittenByMain++;
// Thread.yield();
// System.out.println("test");
// new Random().nextInt();
} while (onlyWrittenByThread < 10);
System.out.println("main done");
}
}
volte in esecuzione questa uscita volontà "filo fatto" e poi appendere per sempre. A volte è completo. Quindi il thread vede le modifiche apportate dal thread principale, ma apparentemente main non vede sempre la modifica apportata dal thread?
Se inserisco il sistema, o Thread.yield, o la chiamata casuale o rendiamo volatile soloWrittenByThread, esso viene completato ogni volta (provato circa 10 volte).
Ciò significa che il post di blog di cui faccio il riferimento sopra non è corretto? Che devi avere una barriera di memoria anche nello scenario single writer?
rapportoNessuno abbastanza risposto a questa domanda in modo penso di Immagino che è probabile corretto che una barriera di memoria non è necessaria, ma senza qualcosa per creare il caso, prima, il compilatore Java e hotspot può fare ottimizzazioni (ad esempio, sollevamento) che lo farà non fare ciò che si vuole.
Hai ancora di preoccuparsi di una scrittura incompleta, vale a dire la lettura la variabile quando è stato solo in parte scritto. Se le scritture sono atomiche, stai bene. – theglauber
È necessario almeno "volatile". Non ci sono garanzie che una scrittura su una variabile non volatile da un thread sarà _ever_ visibile da altri thread. 'volatile' lo garantisce! – fge
@ fge, puoi fornire una documentazione definitiva per questo? Sto cercando di leggere il capitolo 17 delle specifiche, ma non vedo che cosa supporta la tua richiesta. Però, forse è la mancanza di una dichiarazione che confuta è il punto. – mentics