Questo codice da Effective Java (Articolo 66): (senza sincronizzazione o volatili questo non finisce mai)Perché il thread si comporta in modo diverso con il corpo del metodo di esecuzione diverso?
public class ThreadPractice {
static boolean canrunstatic;
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (!canrunstatic){i++;}
System.out.println("finished");
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
canrunstatic = true;
}
Come Bloch menzionato nel capitolo che non potrà mai scrivere "finito" per la console. Ho giocato in giro con questa classe, e aggiungo che la linea per il metodo run eseguibile:
System.out.println("im still running");
Con questo ciclo while non solo incrementare i ma la stampa fuori questa stringa in ogni ciclo. Ma quello che mi fa impazzire, che in questo modo il thread si ferma dopo 1 secondo, quando il filo principale ritorna dal sonno.
modificata: (si arresta senza volatili/sincronizzazione)
public class ThreadPractice {
static boolean canrunstatic;
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (!canrunstatic){i++;System.out.println("im still running");}
System.out.println("finished");
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
canrunstatic = true;
}
Allora, qual è la logica dietro questo?
che non è specificato da nessuna parte nel modello di memoria. La scrittura sulla console è un'operazione esterna nel JMM, ma ciò non garantisce la sincronizzazione e le quote non creano sincronizzazioni con lo spigolo. Quindi questa non è una spiegazione per la logica dietro questo. – MinecraftShamrock
Buon punto, questa è la causa, ma non è necessario che ciò accada. Ho aggiornato la risposta per riflettere questo. – Thirler