2017-08-17 5 views
0

次のコードを実行すると、プログラムは終了せず、予想される動作であるwhileループでスタックされます。Javaスレッド結合によってスレッドの連続実行が作成されます

public class MyClass implements Runnable { 
    public static final int NO_OF_THREADS = 100; 
    private static int count; 
    private static Set<Integer> set = new HashSet<>(); 
    @Override 
    public void run() { 
     for(int i=0 ;i<10000; i++) { 
      set.add(count++); 
     } 
    } 
    public static void main(String[] args) throws Exception { 
     Thread[] threadArray = new Thread[NO_OF_THREADS]; 
     for(int i=0; i<NO_OF_THREADS; i++) { 
      threadArray[i] = new Thread(new MyClass()); 
     } 
     for(int i=0; i<NO_OF_THREADS; i++) { 
      threadArray[i].start(); 
      //threadArray[i].join(); 
     } 
     while(set.size()!=1000000) {} 
    } 
} 

join()のコメントを外すと、プログラムは常に終了します。さらに、スレッドが実行されるシーケンスを印刷するようにコードを修正したとき、結合を使用して、Thread-0は最初にThread-1に続いて適切な番号付けシーケンスでタスクを完了することが観察されました。

JVM スケジューラの期待された動作またはidiosyncrasiesの1つだけですか?

+0

これは[競合条件](https://en.wikipedia.org/wiki/)です。 Race_condition) – litelite

+0

コメントを付けると競合状態が発生しますが、コメントは解除されません。それが問題です。 – azuri

+3

'join 'は、メインスレッドが新しいスレッドを開始する前にスレッドが終了するのを待たせるため、コメントを外したときに競合が発生しません。だから、あなたは一度に1つのスレッドしか持っていません。 – litelite

答えて

1

あなたがスレッドよりも、同じ時間であなたのセットにアクセスする必要があります、あなたはカウントがより多くのために同じになる場合には、競合状態を持っていますが、コメント・ジョインではい、これは、予想される動作であります基本的には同じ場所に複数の要素を追加するので、ループの状態は常に真となり、アプリケーションは終了しません。

あなたの参加がコメントされていない場合、各スレッドが終了するまで、メインスレッドはブロックされ、ループの次の反復に移動するので、追加されたすべての要素が異なるため、同時アクセスはありません。

+0

私の質問は、競合状態が繰り返しカウント値の原因であることに同意する最初のケースではありません。私の質問は、私がjoin()のコメントを外したときに、2番目のケースで競合条件が存在しない理由です。 – azuri

+0

@azuri私はそれを説明しました。それを確認してください。 –

+0

'HashSet'の同時変異も多くの問題を引き起こす可能性があります。詳細については、この質問を参照してください。https://stackoverflow.com/q/22632552/1398418 @azuri – Oleg

関連する問題