【问题标题】:multiple threads call wait(), then notify(), result is deadlock多线程调用wait(),然后notify(),结果死锁
【发布时间】:2016-05-17 20:37:13
【问题描述】:

我想知道如何解决以下问题: 我创建了多个相同类型的线程。它们都有一个带有定时while循环和同步块的运行方法,其中首先调用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);
        }
    }
}

感谢您的回答...

【问题讨论】:

  • 我不明白。你为什么要写这段代码,因为知道wait 将永远阻塞,因为notify 它不存在任何东西?你想做什么?
  • 你误解了如何使用等待和通知,把这段代码扔掉,阅读docs.oracle.com/javase/tutorial/essential/concurrency/…
  • 任务是找出死锁情况的原因和解决方案。我确实理解为什么线程卡在 wait()-position ,但我不知道如何解决它。我可以在“外部”调用 notify()/notifyAll() 以保持线程运行吗?
  • @drwood187 是的,如果一个线程调用wait,另一个线程需要调用notify[All]
  • 原因是,在其他线程调用intList.notify() 之前,对intList.wait() 的调用不会返回。您的所有线程都执行 wait() 调用,然后它们中的任何一个都可以执行 notify() 调用。如果他们都在等待,那么谁来叫醒他们?

标签: java multithreading wait synchronized notify


【解决方案1】:

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

让我们看一下您的代码。通过在Deadlock3 的构造函数中调用new Thread(this).start(); 来启动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
...

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-16
    • 2018-11-13
    相关资源
    最近更新 更多