Il modello di memoria Java fornisce garanzie di verifica prima per le interazioni del pool di thread? In particolare, le scritture effettuate da un thread di thread pool thread prima della fine dell'esecuzione di un elemento da una coda di lavoro saranno visibili a un thread di lavoro che esegue successivamente l'elemento successivo dalla coda?Il modello di memoria Java si verifica prima delle interazioni del pool di thread
La specifica (che personalmente trovo questa FAQ utile: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#synchronization) stabilisce che "Una chiamata a start() su un filo avviene prima di qualsiasi azione nel thread iniziato.", O in poche parole, la memoria scrive fate prima di iniziare un thread verrà eseguito prima e visibile al metodo run() che il thread avviato sta per eseguire. È diverso per un pool di thread, l'avvio() normalmente viene eseguito prima di eseguire una scrittura. Si consideri un semplice flusso di lavoro in cui un oggetto contesto è mutato e passa all'azione successiva:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
private static class Container<T> {
private T value;
public T get() {
return value;
}
public void set(T newValue) {
value = newValue;
}
}
public static void main(String[] args) {
final Container<Integer> sharedObject = new Container<>();
final ExecutorService executor = Executors.newFixedThreadPool(10);
// SKIPPED: pre-warm the executor so all worker threads are start()'ed
final Runnable read =() -> System.out.println("Got " + sharedObject.get());
Runnable write =() -> {
sharedObject.set(35);
executor.execute(read);
};
executor.execute(write);
// SKIPPED: wait until done
}
}
È la scrittura per sharedObject.value
da write.run()
garantito per essere visibile (non chiedere su ordinazione, questo è ovvio) per read.run()
?
(PS: ho capito che, per rendere value
volatile
non fornire questa garanzia)
Update (complementare alla risposta): pacchetto di documentazione di riepilogo per java.util.concurrent
riassume garanzie di coerenza di memoria forniti dal linguaggio ed estesi dal quadro : https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility
Io non ti seguo - la tua conclusione è opposta alla citazione che hai usato ... Nell'esempio dell'opzione, c'è sicuramente una relazione hb tra 'sharedObject.set (35)' e 'println'. Forse hai perso il fatto che la seconda attività viene aggiunta alla coda * dalla prima attività *, non nel thread principale. – assylias
@assylias Hai ragione, mi è sfuggito questo fatto. Come suggerirebbe la formulazione della mia risposta, sto parlando di due compiti aggiunti in modo indipendente, non di un compito che ne presenta un altro. – Andreas
Grazie per aver notato una discrepanza tra la mia domanda e l'esempio. L'esempio è ciò che volevo sapere ma non riuscivo a capire la domanda, sarebbe stato: sono le azioni di scrittura in 'write' create prima di sottoporre' read' visibile al thread 'read'. – Pavel