2016-08-29 2 views
1

Ich bin neu in Java und probierte die Synchronisation mit einem Beispielprogramm aus, um Nummern bis 100 mit MultiThreading hinzuzufügen. Und folgendes ist Code, den ich mir ausgedacht habe. Wenn ich den Code teste, gibt es manchmal den korrekten Wert von 4590, aber manchmal gibt es nicht den richtigen Wert. Kann jemand darauf hinweisen, was mache ich falschJava Synchronization Trouble

class Counter{ 
    Integer counter = 0; 

    public void increment(int i){ 
     synchronized (counter){ 
      counter += i; 
     } 
    } 
} 

class ObjectTest implements Runnable{ 

    int i; 
    Counter blah; 

    public ObjectTest(Counter counter,int i){ 
     blah =counter; 
     this.i = i; 
    } 
    @Override 
    public void run() { 
     blah.increment(i); 
    } 
} 

public class SyncTest { 

    public static void main(String args[]) throws InterruptedException { 
     ThreadPoolExecutor executor = new ThreadPoolExecutor(4,10,60, TimeUnit.SECONDS,new SynchronousQueue<Runnable>(), new ThreadPoolExecutor.CallerRunsPolicy()); 
     Counter counter = new Counter(); 
     for (int index = 0; index < 100; index++) { 
      ObjectTest objectTest = new ObjectTest(counter,index); 
      executor.execute(objectTest); 
     } 
     executor.shutdown(); 
     while (!executor.isTerminated()){ 
      Thread.sleep(1000L); 
     } 

     System.out.println(counter.counter); 
    } 
} 

Antwort

2

können Sie nicht auf counter synchronisieren, weil es eine Integer ist, die unveränderlich ist. Daher erstellt counter += i ein neues Objekt Integer, das nicht das gleiche ist, das synchronisiert wurde.

Sie können es int counter machen und haben eine separate Object lock = new Object();, Synchronisierung auf lock.

+2

Sie können auf einer Integer (oder einem Objekt) synchronisieren, nur nicht die, die Sie inkrementieren ... – RealSkeptic

+0

Ja meine Aussage galt für diesen bestimmten Code. Sie können auch auf der Ganzzahl, die Sie inkrementieren, synchronisieren, es wird nur nicht zu gut funktionierendem Code führen. – Kayaman

+0

Sie verstehen das Problem offensichtlich, aber Ihre Antwort ist nicht sehr ähnlich zu der Art, wie Neulinge denken. Neulinge verstehen den Unterschied zwischen Objekten und Variablen und Ausdrücken nicht vollständig. Sie sagen "weil Integer unveränderlich ist", aber was Sie wirklich meinen, ist, "weil" Integer "-Objekte unveränderlich sind, muss die' counter'-Variable _mutable_ sein. " Es ist die Veränderlichkeit der Counter-Variablen, die das Problem verursacht, nicht die Unveränderlichkeit von Integer-Objekten. –