程序在两个线程交替打印偶数奇数后无限期挂起

时间:2014-12-31 13:44:00

标签: java multithreading

我正在尝试线程间通信。在下面的程序中,我试图使两个线程打印均匀和dd数字交替。他们正确打印数字,但程序永远不会退出。我认为两个线程都在等待锁定,陷入僵局。请帮助我了解如何解决这种情况

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然后挂断

2 个答案:

答案 0 :(得分:4)

打印出100后,偶数线程就会输入lock.wait();。没有什么可以把它从等待中取出(另一个线程已经终止,或者将立即终止),所以它永远存在于那里。

答案 1 :(得分: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