多线程调用wait(),然后notify(),结果是死锁

时间:2016-05-17 20:37:14

标签: java multithreading wait synchronized notify

我想知道如何解决以下问题: 我创建了多个同类线程。它们都有一个带有定时while循环和synchronized-block的run方法,其中首先调用wait(),然后调用notify()。这导致所有线程都处于wait()状态,并且没有一个调用notify()。 我怎样才能克服这种僵局?有没有使用wait()/ notify()的解决方案?

public class Deadlock3 implements Runnable {
    LinkedList<Integer> intList;
    public Deadlock3(LinkedList<Integer> list) {
        intList = list;
        new Thread(this).start();
    }
    public void run() {
        long startTime = System.currentTimeMillis();
        try {
            while (System.currentTimeMillis() - startTime < 10) {
                synchronized (intList) {
                    Integer number = intList.removeFirst();
                    System.out.println(number + " removed");
                    number = (number + 3) % 21;
                    intList.addLast(number);
                    System.out.println(Thread.currentThread().getName()+" - "+number + " added");
                    intList.wait();
                    intList.notifyAll();
                }
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<Integer>();
        for (int i = 0; i < 20; i++) {
            list.add(i);
        }
        for (Integer i : list) {
            System.out.println(i);
        }
        for (int i = 0; i < 4; i++) {
            new Deadlock3(list);
        }
    }
}

感谢您的回答......

1 个答案:

答案 0 :(得分:0)

  

如何克服这种僵局?有没有使用wait()/ notify()的解决方案?

让我们来看看你的代码。通过在new Thread(this).start();的构造函数中调用Deadlock3来启动4个线程。顺便说一句,这是一个非常糟糕的模式,因为线程可以在对象完全构造之前开始使用字段。最好这样做:

for (int i = 0; i < 4; i++) {
   new Thread(new Deadlock3(list)).start();
}

但那不是问题。当Deadlock3开始时,第一个线程在intList上同步,进行一些计数和填充,并调用intList.wait()。这会等到有人拨打intList.notify()notifyAll()。第一个线程进入休眠等待并释放intList锁。问题是每个线程都经历了相同的过程。他们都在intList等待,没有人到达notifyAll()

真正的问题是调用wait()并通知的重点是什么?在我看来你不需要它们,它们可以被删除。如果您需要它们,请解释原因?

当我删除这些行并在吐出一堆以下周期后运行程序完成:

...
18 removed
Thread-3 - 0 added
19 removed
Thread-3 - 1 added
20 removed
Thread-3 - 2 added
0 removed
Thread-3 - 3 added
1 removed
Thread-3 - 4 added
2 removed
...

希望这有帮助。