【发布时间】:2016-05-28 17:34:38
【问题描述】:
两个线程在同一个监视器上等待,例如,如果一个线程调用 wait on 'lock',而另一个获取监视器的线程也在通知第一个线程之前调用 wait。现在两个线程都在等待,但没有人收到通知。我该怎么称呼这种情况?这能叫死锁吗?
编辑:
假设这是仅有的两个线程,并且无法从其他地方通知它们。
更新:我刚刚创建了我所描述的情况。当更改器线程在侦听器线程之前启动时,以下代码大部分时间都可以正常工作。但是,当我在转换器之前启动侦听器时,程序在打印两行(一行来自转换器,另一行来自侦听器线程)后挂起。我在 changer 之前调用 listener 的情况会被称为死锁吗?
package demo;
public class ProducerConsumer {
public static int SAMPLE_INT = 0;
public static void main(String[] args) {
PC pc = new PC();
Thread changer = new Thread(new Runnable() {
public void run(){
try {
pc.producer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread listener = new Thread(new Runnable(){
public void run() {
try {
pc.consumer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
changer.start();
listener.start();
}
}
class PC {
Object lock = new Object();
public void producer() throws InterruptedException {
synchronized(this){
for (int i=0; i<5; i++){
ProducerConsumer.SAMPLE_INT++;
System.out.println("Changed value of int to: " + ProducerConsumer.SAMPLE_INT);
wait();
notify();
}
}
}
public void consumer() throws InterruptedException{
synchronized(this){
for (int i=0; i<5; i++){
System.out.println("Receieved Change: " + ProducerConsumer.SAMPLE_INT);
notify();
wait();
}
}
}
}
在监听器之前启动转换器时的输出:
将 int 的值更改为:1
收到的零钱:1
将 int 的值更改为:2
收到的零钱:2
将 int 的值更改为:3
收到的零钱:3
将 int 的值更改为:4
收到的零钱:4
将 int 的值更改为:5
收到的更改:5
程序终止。
在更改程序之前启动侦听器时的输出:
收到的零钱:0
将 int 的值更改为:1
程序不会终止。
谢谢。
【问题讨论】:
-
你创建的锁对象没有被使用。此外,当调用'wait'时,它应该在一段时间内(!conditionMet){lock.wait(); ... }。使用同步方法/块和调用等待/通知有许多细微差别。继续阅读,你会更清楚。至于您的问题,正如我们在下面的回答中进行了辩论,由您决定。我和 Krashimir 说这不是僵局,而安迪和其他人说这是僵局。通读讨论并自己决定:) 干杯!
-
没有人拥有“死锁”这个词,你可以随心所欲地使用它,无论你如何使用它,都会有有人抱怨你在使用它它错了。 IMO,他们都会接受的最广泛的定义至少部分正确是:一组线程,其中没有一个成员能够取得进展,直到至少一个其他成员取得进展。跨度>
标签: java multithreading deadlock