Pourquoi est i++ pas atomique?

Pourquoi est i++ pas atomique en Java?

Pour obtenir un peu plus profondément en Java, j'ai essayé de compter combien de fois la boucle dans les threads sont exécutées.

J'ai donc utilisé une

private static int total = 0;

dans la classe principale.

J'ai deux fils.

  • Thread 1: Imprime System.out.println("Hello from Thread 1!");
  • Filetage 2: Imprime System.out.println("Hello from Thread 2!");

Et je compte les lignes imprimées en 1 fil et du fil 2. Mais les lignes de fil 1 + lignes de fil 2 ne correspondent pas au nombre total de lignes imprimées.

Voici mon code:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Test {
private static int total = 0;
private static int countT1 = 0;
private static int countT2 = 0;
private boolean run = true;
public Test() {
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
newCachedThreadPool.execute(t1);
newCachedThreadPool.execute(t2);
try {
Thread.sleep(1000);
}
catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
run = false;
try {
Thread.sleep(1000);
}
catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println((countT1 + countT2 + " == " + total));
}
private Runnable t1 = new Runnable() {
@Override
public void run() {
while (run) {
total++;
countT1++;
System.out.println("Hello #" + countT1 + " from Thread 2! Total hello: " + total);
}
}
};
private Runnable t2 = new Runnable() {
@Override
public void run() {
while (run) {
total++;
countT2++;
System.out.println("Hello #" + countT2 + " from Thread 2! Total hello: " + total);
}
}
};
public static void main(String[] args) {
new Test();
}
}
  • Pourquoi n'essayez-vous pas avec AtomicInteger?
  • Voir aussi: l'autre DONC, la question, ++ pas considéré atomique, Simultanéité en Java.
  • pourquoi dites-vous AtomicInteger n'est pas atomique? Vous pouvez utiliser la getAndIncrement la méthode pour ce faire. Il est atomique.
  • la JVM a un iinc opération d'incrémentation de nombres entiers, mais qui ne fonctionne que pour les variables locales, où la simultanéité n'est pas un sujet de préoccupation. Pour les champs, le compilateur génère de lecture-modification-écriture séparément.
  • Pourquoi voudriez-vous même s'attendre à être atomique?
  • Même sur le matériel qui met en œuvre un "incrémenter emplacement de stockage" de l'enseignement, il n'y a aucune garantie que c'est thread-safe. Tout simplement parce qu'une opération peut être représenté comme un seul opérateur ne dit rien à ce sujet un fil de sécurité.
  • Freak: même si il y avait un iinc instruction pour les champs, ayant une seule instruction ne permet pas de garantir l'atomicité, par exemple, la non-volatile long et double d'accès sur le terrain en ne garantissant pas être atomique, indépendamment du fait qu'elle est effectuée par une seule instruction bytecode.

InformationsquelleAutor Andie2302 | 2014-08-06