2016-08-29 13 views
1

私はjavaを使い慣れていないので、multiThreadingを使用して100までの数字を追加するサンプルプログラムとの同期を試していました。そして、以下は私が思いついたコードです。私はコードをテストするときに時々4590の正しい値を与えるが、時には正しい値を与えない。誰もが、私はそれが不変であるInteger、だからあなたがcounterで同期することはできません間違っJava同期の問題

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); 
    } 
} 

答えて

2

をやっていると指摘することができます。したがって、counter += iは、新しいIntegerオブジェクトを作成します。このオブジェクトは、同期されたものと同じではありません。

int counterにすることができ、lockに同期して別のObject lock = new Object();を持つことができます。

+2

あなたは、増分しているものではなく、整数(または任意のオブジェクト)で同期することができます... – RealSkeptic

+0

はい私の声明はこの特定のコードに適用されました。増分しているIntegerで同期することもできますが、うまく動作するコードが得られません。 – Kayaman

+0

あなたは明らかにこの問題を理解していますが、あなたの答えは初心者の考え方にあまり似つかわしくありません。初心者は、オブジェクトと変数と表現の違いを完全に把握していません。 Integer is immutableなので、本当に意味するのは、 'Integer'オブジェクトは不変なので、' counter'変数は_mutable_でなければなりません。それは問題を引き起こすカウンタ変数の可変性であり、Integerオブジェクトの不変性ではありません。 –