2013-03-08 12 views
8

Ich weiß, Inkrementoperation ist in C++ ohne Sperre nicht atomar.Ist iinc Atom in Java?

Will JVM hinzufügen jede Sperre auf die Implementierung von iinc Anweisung?

Antwort

17

Kein sein nicht

  • den aktuellen Wert von c abrufen.
  • Increment der abgerufene Wert um 1.
  • lagern c der inkrementierte Wert zurück.

Java Documentation for Atomicity and Thread Interference

Sie müssen entweder synchronized Schlüsselwort verwenden oder AtomicXXX Methoden zur Thread-Sicherheit verwenden.

UPDATE:

public synchronized void increment() { 
    c++; 
} 

oder

AtomicInteger integer = new AtomicInteger(1); 
//somewhere else in code 
integer.incrementAndGet(); 

Lesen Sie auch: Is iinc atomic in Java?

+0

sollten Sie die Concurrency-Dokumentation von Java lesen, die ziemlich gut für das Verständnis der grundlegenden Konzepte von Java Concurrency ist. –

+0

Danke, lese es jetzt. In 1 Minute annehmen. – StarPinkER

+0

Sicher froh zu helfen! –

3

Nein, es nicht atomar ist, kann der Bytecode mit anderen Threads verschachtelt bekommen.

6

es ist nicht nicht und es kann echte Probleme verursachen. Dieser Test soll 200000000 drucken, aber es tut wegen Störung

static int n; 

public static void main(String[] args) throws InterruptedException { 
    Runnable r = new Runnable() { 
     public void run() { 
      for(int i = 0; i < 100000000; i++) { 
       n++; 
      } 
     } 
    }; 
    Thread t1 = new Thread(r); 
    Thread t2 = new Thread(r); 
    t1.start(); 
    t2.start(); 
    t1.join(); 
    t2.join(); 
    System.out.println(n); 
} 

Hinweis einzufädeln, dass volatile das Problem nicht lösen.

+0

+1 für auch einschließlich der flüchtigen:) –

+1

Tatsächlich verwendet dieser Code nicht einmal die 'IINC'-Anweisung, um das' n'-Feld zu inkrementieren. 'IINC' wird nur für lokale Variablen verwendet und in diesem Fall nur für' i ++ '. – Clashsoft

1

i ++ ist nicht atomar in Java.
Es ist besser,

AtomicInteger atomic= new AtomicInteger(1); 

Es gibt Methoden, wie

mit obigen Verfahren
atomic.getAndDecrement(); 
atomic.getAndIncrement(); 
atomic.decrementAndGet(); 
atomic.incrementAndGet(); 

jede Operation atomar wäre definiert zu verwenden.

Diese Klasse kommt unter java.util.concurrent.atomic Paket. Java 1.5 hat viele Funktionen für Sicherheit und Parallelität von Threads hinzugefügt.

0

Es ist nicht atomar. Hier ist die erzeugte Byte-Code für ein Post-Inkrement eines statisches int:

0 getstatic 18; // Load value of variable. 
3 iconst_1; 
4 iadd; 
5 putstatic 18; // Store value. 
6

{Obwohl es bereits eine akzeptierte Antwort ist, ich wollte etwas klären, damit die späte und technisch unnötige Antwort}

Die Antwort auf Ihre Frage hängt davon ab, ob Sie die IINC Anweisung oder was andere Antworten beziehen sich auf die ++ Betreiber.

Mit ++ auf einem statisches oder Instanzfeld ist nichts anderes als erhalten, erhöht und eingestellt, so ist es nicht Atome (die anderen Antworten erklären diese im Detail).

Aber

Da Sie, wenn gefragt IINCAnweisung atomar ist, ist dies nicht die richtige Antwort. Tatsächlich adressiert keine der Antworten auf diese Frage die Anweisung, alle scheinen auf dem Operator zu basieren, der auf Instanz- oder statischen Feldern verwendet wird.


Die IINC Anweisung nur auf lokale Variablen arbeitet. Wie der Name schon sagt, sind sie nur lokal, und nur aus einem sehr begrenzten Umfang zugänglich. Daher ist es nicht möglich, von einem anderen Thread auf eine lokale Variable zuzugreifen. Dies bedeutet, dass es egal ist, ob der Befehl atomar ist oder nicht.

+0

Danke für Ihre Antwort! – withparadox2

+0

Schön geklärt! Link zu deiner Antwort von meiner Antwort hinzugefügt. –