对于以下程序,当线程完成其工作时,为什么主线程不会停止?

时间:2018-06-11 01:12:23

标签: java multithreading

这个程序可以通过不同的线程打印备用数字,但是当打印0-9的所有数字时为什么这个程序不会停止?我必须手动停止我的申请。

public class EvenOddPrinter  implements Runnable{

private AtomicInteger num = new AtomicInteger(0);
private Object lock = new Object();

@Override
public void run() {
    synchronized (lock){
        while (num.get()<10){
            System.out.println(num.getAndAdd(1) + " - "+Thread.currentThread().getName());
            lock.notify();
            try {
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
}

public class Executor {
    public static void main(String[] args) throws InterruptedException {
        EvenOddPrinter eop = new EvenOddPrinter();
        Thread t1 = new Thread(eop);
        Thread t2 = new Thread(eop);
        t1.start();
        t2.start();
    }
}

3 个答案:

答案 0 :(得分:2)

这是因为最后一个帖子卡在waitnotifyAll将通知所有等待的线程(如果有)并释放锁定。

while (num.get()<10){
  // existing implementation
}
lock.notifyAll();

答案 1 :(得分:0)

一旦数量达到8,第一个线程就会调用notify()并转到wait()。然后第二个线程产生数字9并调用notify()并转到wait()。然后,第一个线程无法进入条件中指定的循环内部,因此,它退出synchronized和block并完成,但第二个线程仍在等待。一旦其中一个线程退出synchronized块,就必须有一个notifyAll()机制,这正是我所做的。

@Override
public void run() {
    synchronized (lock){
        while (num.get()<10){
            System.out.println(num.getAndAdd(1) + " - "+Thread.currentThread().getName());
            lock.notify();
            try {
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        lock.notifyAll();
    }

此外,当我使用AtomicInteger(或反过来)时,锁是没有意义的。

答案 2 :(得分:0)

第二个线程t2最后一直在等待锁定,而t1不再执行notify()因为while条件变为false。你必须把lock.notify();在while循环之外的语句。