2017-01-14 4 views
0

私のプログラムでは、スレッドT1は新しいスレッドT2を生成し、そのスレッド(すなわちT2.join)に対してjoinを呼び出し、この新たに生成されたスレッドT2はT1(すなわちT1.join)でjoinを呼び出します。これはスレッドのブロックを引き起こしています。どのようにこれを克服することができます。 私のプログラムJavaスレッド参加メソッド

public class PositiveNegativeNumberProducerV1 { 
    static Thread evenThread, oddThread; 

    public static void main(String[] args) { 

     oddThread = new Thread(new OddProducer(evenThread), "oddThread"); 
     oddThread.start(); 


    } 

} 
class EvenProducer implements Runnable { 
    Thread t; 
    EvenProducer(Thread t) { 
     this.t= t; 
    } 
    public void run() { 
     for(int i=1; i<=100; i++) { 
      if(i%2==0) { 
       System.out.println("i = "+i+":"+Thread.currentThread().getName()); 
       try { 
        System.out.println("Now join will be called on "+t.getName()+" by thread "+Thread.currentThread().getName()); 
        t.join(); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 

class OddProducer implements Runnable { 
    Thread t; 
    OddProducer(Thread t) { 
     this.t= t; 
    } 
    public void run() { 
     for(int i=1; i<=100; i++) { 
      if(i%2!=0) { 
       System.out.println("i = "+i+":"+Thread.currentThread().getName()); 
       try { 
        if(t==null) { 
         t = new Thread(new EvenProducer(PositiveNegativeNumberProducerV1.oddThread), "evenThread"); 
         t.start(); 
        } 
        if(t.isAlive()) { 
         System.out.println("evenThread is alive and join will be called on "+t.getName()+" by thread "+Thread.currentThread().getName()); 
         t.join(); 
        } 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 
+4

これを行わないでください。それはあなたがそれを克服する方法です。 2人が同じドアを歩きたいと想像してみてください。それぞれが自分自身を通過する前に相手が歩き回るのを待つ - これはデッドロックの定義です。 –

+0

あなたの文に動詞がないボリス。 – GhostCat

+0

@GhostCat動詞は敗者のためのものです。 Appleの自動修正に少なくとも従ってください。 –

答えて

0

あなただけの出力を同期させたい場合は:1 2 3 4 ...そして、あなたは(すなわち、runメソッドを残して、スレッドの終了を待つ)に参加を使用しないでください。セマフォー・オブジェクトに対してwait()とnotify()のペアを使用することを検討してください。

 Object sema = new Object(); 

     new Thread(new Runnable() { 
      @Override 
      public void run() 
      { 
       for (int i = 1; i <= 100; i++) 
       { 
        if (i % 2 == 0) 
        { 
         try 
         { 
          System.out.println("Going to wait for the odd thread - " 
           + Thread.currentThread().getName()); 
          synchronized (sema) 
          { 
           sema.wait(); 
          } 

          System.out.println("i = " + i + ":" + Thread.currentThread().getName()); 

          System.out.println("Going to notify the odd thread - " 
           + Thread.currentThread().getName()); 
          synchronized (sema) 
          { 
           sema.notify(); 
          } 
         } 
         catch (InterruptedException e) 
         { 
          e.printStackTrace(); 
         } 
        } 
       } 
      } 
     }, "Even").start(); 

     new Thread(new Runnable() { 
      @Override 
      public void run() 
      { 
       for (int i = 1; i <= 100; i++) 
       { 
        if (i % 2 != 0) 
        { 
         System.out.println("i = " + i + ":" + Thread.currentThread().getName()); 
         try 
         { 
          System.out.println("Going to notify the even thread" 
           + Thread.currentThread().getName()); 
          synchronized (sema) 
          { 
           sema.notify(); 
          } 
          System.out.println("Going to wait for the even thread" 
           + Thread.currentThread().getName()); 
          synchronized (sema) 
          { 
           sema.wait(); 
          } 
         } 
         catch (InterruptedException e) 
         { 
          e.printStackTrace(); 
         } 
        } 
       } 
      } 
     }, "Odd").start(); 
関連する問題