2016-05-12 5 views
0

私はすべてのスレッドによって「グローバルカウンタ」に1を追加しようとしました。したがって、 "グローバルカウンタ"の結果は10でなければなりません。 すべてのスレッド結果を出力します。ほとんどの場合、最後の結果は10.ですが、10が最後の数字ではありません。私は同期またはロックを使用していますが、動作しません。初心者| threadPool |すべての結果を印刷する|間違った結果

ありがとうございます。私は英語があまりにも悪くないことを願っています。

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class Hauptprogramm { 

public static final int MAX_THREADS = 10; 
public static int globalCounter; 

public static void main(String[] args) { 

// create a pool of threads, 10 max jobs will execute in parallel 
ExecutorService threadPool = Executors.newFixedThreadPool(MAX_THREADS); 

// submit jobs to be executing by the pool 
for (int i = 0; i < MAX_THREADS; i++) { 
    threadPool.submit(new Runnable() { 

    public void run() { 
     // some code to run in parallel 
     globalCounter++; 


     String originalName = Thread.currentThread().getName(); 
     System.out.println("Result: "+globalCounter+" "+originalName); 


     try { 
     Thread.sleep(1000); 

     } catch (InterruptedException e) { 

     } 

    } 
    }); 
} 
    threadPool.shutdown(); 
    } 
} 
+0

は、結果がランダムで –

+0

質問で出力を印刷します。結果:5 pool-1-thread-1 結果:6 pool-1-thread-6 結果:5 pool-1-thread-4 結果:5 pool-1-thread-2 結果:5 pool-1-thread-3 結果:5 pool-1-thread-5 結果:7 pool-1-thread-7 結果:8 pool-1-thread-8 結果:9 pool-1-thread- 9 結果:10 pool-1-thread-10 – Cashew

+1

これは、同期なしでは期待される結果です。 – Fildor

答えて

1

このテストで期待されていたことは、評判がまだ50ほどないので、私はコメントを追加できません。

Javaスレッドが上位レベルからのリソース割り当てを制御していないJVMで実行されている場合、別のスレッドの実行を開始するスレッドがあることが確認されていれば、リリースロックメカニズムを使用しますが、あなたがそれを順番に実行するかどうか調べるには、お互いに実行する必要のあるスレッドを認識するためのロジックを実行する必要があります。

+0

\t synchronized(Hauptprogramm.class){...}これで十分ですか?結果は1 2 3 4 5 ... 10になります。あまりにも簡単だと思われる – Cashew

+0

ループと同期ブロックによって順次実行されるため、シーケンシャルであることがありました。この場合、スレッドは順番に実行されません。グローバルカウンタの前に割り込みをスワップすると、別の結果が表示されることがあります。 これが期待される結果であれば、それは有効です。 – salirajr

+0

同意します;)JVMを*コマンドすることはできますが、強制することはできません。 + 1_ –

0

私はこれが今だと思う:

  public void run() { 
       synchronized(Hauptprogramm.class) 
        { 


       globalCounter++; 

       String originalName = Thread.currentThread().getName(); 
       System.out.println("Result: " + globalCounter + " " + originalName); 

       try { 
        Thread.sleep(100); 

       } catch (InterruptedException e) { 

       } 

        } 
      }}); 
     } 

    threadPool.shutdown(); 
} 
} 
+0

実際、これは同期範囲の貧弱な選択です。同期化されたブロックを可能な限り小さくしたい(ただし、必要なだけ長く)。考える:ここで重要なリソースは何ですか? - globalCounter。したがって、globalCounterが使用されている部分だけを同期する必要があります。つまり、スレッドは並列パーツを持つことはありません(またはそれに近いものはほとんどありません)。したがって、スレッドを1つだけ増分することもできます。 – Fildor

+0

@Fildorしかし、try-catch部分も同期させないと動作しない – Cashew