2017-01-14 4 views
0

В моей программе Thread T1 порождает новый поток T2 и вызывает соединение в этом потоке (т. Е. T2.join), и этот недавно порожденный поток T2 вызывает соединение на T1 (т. Е. T1.join). Это вызывает блокировку потока. Как это можно преодолеть. Мои программыМетод Threading Threading

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

Не делайте этого; вот как вы его преодолеваете. Представьте себе, что два человека хотят пройти через одну дверь; каждый ждет другого, чтобы пройти, прежде чем пройти через себя - это само определение тупика. –

+0

Борис, ваше предложение отсутствует глагол. – GhostCat

+0

@GhostCat глаголы для проигравших. По крайней мере, автоматически адаптироваться к Apple. –

ответ

0

Если вы просто хотите, чтобы синхронизировать вывод: 1 2 3 4 ... то вы не должны использовать присоединиться (который ждет завершения потока, то есть оставляя метод запуска). Рассмотрим использование пары 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();