2016-12-08 10 views
-1

これまで、私はwaitがいつも正常に動作するように通知する必要があることを知っていました。しかし、以下のコードを試してみると、私はwaitとnotifyの働きについて混乱します.3つのスレッドt1、t2、t3を作成し、私は3つのスレッドを開始したときにt1だけが印刷され、t2とt3は待機状態になり、誰も通知しないので待ち続ける。待ち時間はいつも仕事を知らせる必要がありますか?

しかし、o/pは私にとっては予測不可能です。誰かが私に少しexpalinしてください。下に私のクラスです。

package com.vikash.Threading; 

class T1 implements Runnable { 

    private State state; 

    public T1(State state) { 
     this.state=state; 
    } 

    @Override 
    public void run() { 

     synchronized (state) { 
      while(state.getState()!=1) { 
       try { 
        state.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

      synchronized (state) { 
       System.out.println(Thread.currentThread().getName()); 
       state.setState(2); 
      } 
     } 
    } 
} 

class T2 implements Runnable { 

    private State state; 

    public T2(State state) { 
     this.state=state; 
    } 

    @Override 
    public void run() { 

     synchronized (state) { 
      while(state.getState()!=2) { 
       try { 
        state.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

      synchronized (state) { 
       System.out.println(Thread.currentThread().getName()); 
       state.setState(3); 
      } 
     } 
    } 
} 

class T3 implements Runnable { 

    private State state; 

    public T3(State state) { 
     this.state=state; 
    } 

    @Override 
    public void run() { 

     synchronized (state) { 
      while(state.getState()!=3) { 
       try { 
        state.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

      synchronized (state) { 
       System.out.println(Thread.currentThread().getName()); 
       state.setState(1); 
      } 
     } 
    } 
} 

public class Sequence { 

    public static void main(String[] args) { 

     State state=new State(); 
     Thread t1=new Thread(new T1(state),"First"); 
     Thread t2=new Thread(new T2(state),"Second"); 
     Thread t3=new Thread(new T3(state),"Third"); 
     t1.start(); 
     t2.start(); 
     t3.start(); 
    } 
} 



package com.vikash.Threading; 

public class State { 

    private int state=1; 

    public int getState() { 
     return state; 
    } 

    public void setState(int state) { 
     this.state = state; 
    } 
} 

私は時々、私は第一、第二を取得していますし、それが終了し、時には第一、第二第三に、終了していないのp/oを私のquestion.Theを修正していたコメントを1として。

+1

説明してください。しかし、o/pは私にとっては予測できないかもしれません。* –

+0

多分理由はありませんが、あなたは 'synchronized'をネストしていることに気付いていますか?http://stackoverflow.com/a/10365261/2310289 –

答えて

2

あなたの予想が間違っている、すべてのスレッドが印刷して終了するために、あなたのプログラムが現在書かれているとして、それが可能である(しかし、これは偶然に依存します)

これは、使用して最初のstateにモニターをつかむどのスレッドに依存それらがすべて持っているブロック​​。

、このフローを検討:

  1. T1は、第synchronized (state)ブロックに入ります。 T2およびT3はブロックsynchronized (state)を入力するのを待機しています。
  2. T1はstate.getState() == 1として待たないので、代わり
  3. T1は、スレッド名を出力し、割り当て
  4. T1が
  5. いずれT2またはT3は、それらsynchronized (state)ブロックを入力同期ブロックを出る2 state.stateに、それがあると仮定しますT2(1が最初に入るJavaで未定義の動作であり、おそらくこれはランダムです)state.getState() == 2
  6. T2は、スレッド名を出力し、3からstate.state
  7. を割り当てるよう
  8. だからT2を待ちません3210
  9. T2は同期ブロックを終了します
  10. T3は同期ブロックに入り、待機せず、スレッド名を出力します。
  11. プログラムが完了しました。
関連する問題