Questo richiede la sincronizzazione?
-
25-09-2019 - |
Domanda
Nella classe di seguito, sto usando un singleThreadScheduledExecutor. La mia domanda è, ho bisogno di sincronizzare in giro l'accesso ai dummyInt e dummyBoolean?
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Playground {
/**
* @param args
*/
public static void main(String[] args) {
startThread();
}
private static void startThread() {
ScheduledExecutorService timer = Executors
.newSingleThreadScheduledExecutor();
Runnable r = new Runnable() {
int dummyInt = 0;
boolean dummyBoolean = false;
@Override
public void run() {
dummyInt = dummyInt + 1;
if (dummyBoolean) {
dummyBoolean= false;
} else {
dummyBoolean= true;
}
}
};
timer.scheduleAtFixedRate(r, 0, 100, TimeUnit.MILLISECONDS);
}
}
Soluzione
No, non lo fai. V'è solo un unico filo accedere ai valori, quindi non è necessaria alcuna sincronizzazione.
Altri suggerimenti
Ogni discussione si inizia con questo meccanismo avrà la propria istanza della sottoclasse "Runnable" si definisce e creare un'istanza. Pertanto, non ci può eventualmente essere contesa.
Avete bisogno di? No. Solo un unico filo mai accedere alle variabili nell'implementazione corrente, così è sicuro thread.
sarebbe male prestazioni? Beh, sì, ma non tanto quanto si sarebbe probabilmente aspettare. I moderni compilatori JIT sono molto felice di individuare che la sincronizzazione non è necessaria in uso corrente, ed eliminare praticamente tutti l'overhead del codice compilato - ma ci sarebbe un po 'in testa restando che verificare se l'assunzione di accesso single-threaded era ancora valido. E, naturalmente, c'è il sovraccarico di JITting questo.
sarebbe mai fatto male a non eseguire la sincronizzazione? Beh, forse, se l'implementazione mai cambiato e l'assunzione di accesso unico filo non è più tenuto - e lo sviluppatore fare il cambiamento trascurato tale conseguenza del loro cambiamento
.In realtà, in questo contesto, è che rischia di verificarsi? Forse no - tutto il codice è contenuto in una zona molto piccola ...
probabilmente sarei lasciare un qualche tipo di commento che documenta l'ipotesi. Potrei anche annotare la classe come @NotThreadSafe, se stavo usando il JCIP annotazioni in qualsiasi altro luogo nel mio progetto. Una discussione l'uso di queste annotazioni si possono trovare nel Java Concurrency in Practice libro di Brian Goetz, e il codice sorgente di annotazione e un file jar sono disponibili per il download dal libro sito web .
Non dovete renderlo synchronized
No, ma probabilmente non sarebbe male. Dal momento che si sta utilizzando un newSingleThreadScheduledExecutor che promesse che
Tasks sono garantiti da eseguire sequenziale, e non più di una compito sarà attiva in un dato momento.
, ma se mai cambiare esecutori, lasciare che il Runnable uscire in modo che altri possono invocare, o controllare il valore esterno, quindi ti auguro che avevi sincronizzato esso.
dummyInt = dummyInt + 1;
Questa affermazione è in realtà 3 distinte operazioni:
- Leggi il valore di dummyInt
- Aggiungi 1
- Scrivi la schiena valore dummyInt
Quindi sì si ha bisogno di sincronizzare l'. E 'possibile per un thread per leggere il valore, poi un altro filo fa le tre operazioni, e quando il primo thread termina il valore è aumentato solo da 1 (spero questo senso: P) .dummyBoolean
è simile. Lo si legge in if e la scrittura del nuovo valore.
Modifica
Ci scusiamo per non leggere correttamente alla domanda. Secondo javadoc questo non dovrebbe aver bisogno di sincronizzazione.