我想知道如何解决以下问题: 我创建了多个同类线程。它们都有一个带有定时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);
}
}
}
感谢您的回答......
答案 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
...
希望这有帮助。