2014-12-31 1 views
1

Я пытался обмениваться сообщениями между потоками. В нижеприведенной программе я пытаюсь сделать два потока print even и dd number альтернативно. Они правильно печатают номера, но программа никогда не выходит. Я думаю, что оба потока ждут блокировки, в тупике. Пожалуйста, помогите мне в понимании, как справиться с этой ситуацией.Программа зависает бесконечно после того, как два потока печатают даже вне чисел, альтернативно

package Test; 

import java.util.logging.Level; 
import java.util.logging.Logger; 

public class ConcurrencyTest { 
    public static void main(String [] args) { 
     Object lock = new Object(); 
     Thread t1 = new Thread(new ThreadM("odd",lock)); 
     Thread t2 = new Thread(new ThreadM("even",lock)); 
     t1.setName("Odd thread"); 
     t2.setName("Even thread"); 
     t1.start(); 
     t2.start(); 
    } 
} 

class ThreadM implements Runnable{ 
    int start; 
    int max; 
    Object lock; 
    String startAt; 
    public ThreadM(String startAt, Object lock) { 
     this.start = 1; 
     this.startAt = startAt; 
     this.lock = lock; 
    } 
    @Override 
    public void run() { 
     System.out.println(Thread.currentThread().getName()); 
     try { 
      if("even".equals(startAt)) { 
       printEven(); 
      } else { 
       printOdd(); 
      } 
     } catch (InterruptedException ex) { 
      Logger.getLogger(ThreadM.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    private void printEven() throws InterruptedException { 
     while(this.start <= 100) { 
      if(this.start % 2 == 0) { 
       synchronized(lock) { 
       System.out.println(Thread.currentThread().getName()+"Printing even >> "+this.start); 
       lock.notify(); 
       lock.wait(); 
       } 
      } 
      this.start++; 
      System.out.println(Thread.currentThread().getName()+" >> "+this.start); 
     } 
     System.out.println("done"); 
    } 

    private void printOdd() throws InterruptedException { 
     while(this.start <= 100) { 
      if(this.start % 2 == 1) { 
       synchronized(lock) { 
        System.out.println(Thread.currentThread().getName()+" Printing odd >> "+this.start);    
        lock.notify(); 
        lock.wait(); 
       } 
      } 
      this.start++; 
      System.out.println(Thread.currentThread().getName()+" >> "+this.start); 
     } 
    } 
} 

Вот пример вывода. Числа идут до 100 так, я вставляя последние несколько строк вывода

Even threadPrinting even >> 96 
Odd threadPrinting odd >> 97 
Even threadPrinting even >> 98 
Odd threadPrinting odd >> 99 
Even threadPrinting even >> 100 

Темы печать точно до 100 повесьте трубку

+1

Вы должны смотреть на нить свалку, чтобы получить подсказки о том, где ваши нити застрял. – aliher

+1

После печати вы всегда ждите, так что он будет висеть на последнем результате. –

ответ

4

Отпечатав из 100, то даже нить затем поступает lock.wait();. Нет ничего, что могло бы вытащить его из этого ожидания (другой поток уже или прекратился, или скоро закончится), поэтому он сидит там навсегда.

+0

this.start локально не используется вне каждой темы, так почему же он должен быть атомарным или объявленным изменчивым? Единственный общий объект, который я вижу, - это блокировка. – aliher

+0

@aliher: Вы совершенно правы, спасибо. Я неправильно прочитал код. – NPE

0

Как объясняется NPE, даже поток ждет. Вы должны просто добавить lock.notify() перед выходом из формы нечетной резьбы:

private void printOdd() throws InterruptedException { 
    while(this.start <= 100) { 
     if(this.start % 2 == 1) { 
      synchronized(lock) { 
       System.out.println(Thread.currentThread().getName()+" Printing odd >> "+this.start);    
       lock.notify(); 
       lock.wait(); 
      } 
     } 
     this.start++; 
     System.out.println(Thread.currentThread().getName()+" >> "+this.start); 
    } 
    synchronized(lock) { 
      lock.notify(); 
    } 
} 

Вот конец вывода с этим небольшим изменением:

Odd thread Printing odd >> 99 
Even thread >> 99 
Even thread >> 100 
Even threadPrinting even >> 100 
Odd thread >> 100 
Odd thread >> 101 
Even thread >> 101 
done 
Смежные вопросы