在多线程中检测到不合理的死锁 Java
Unreasonable deadLock detected in multithreading Java
我有一个代码,其中实现 Runnable 的两个线程 classes 是 运行 并且共享 class 缓冲区的公共对象。
虽然我在我的知识范围内正确地使用了同步块和 wait()
和 notify()
方法,但是当我在 try/catch 块中使用 Thread.sleep(0)
休眠线程时,在一些被接受的输出结果之后,它陷入僵局。
当我用 1000 毫秒 Thread.sleep(1000)
休眠线程 Cook 和用 3000 毫秒 Thread.sleep(3000)
休眠线程 Bheem 时未检测到问题
这是线程中常见的生产者-消费者场景,我故意将消费者置于生产者之上。
P.S。 - 我已经给出了从最后一个修剪的 output。实际产量相当大。
以下代码在 Bheem class
public void consume() {
while (ob.buffer >= 1) {
synchronized (ob) {
System.out.println(Thread.currentThread().getName()
+ " started eating Ladoos with currently "
+ (ob.buffer--) + " ladoos in plate");
try {
Thread.sleep(0); // bheem takes 1.5 sec to eat
ob.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized (ob) {
try {
System.out
.println("Plate is empty, bheem will wait for ladoos to serve ");
ob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void run() {
while (true) {
consume();
}
}
这个在库克class
public void produce() {
while (ob.buffer < 5) {
synchronized (ob) {
System.out.println(Thread.currentThread().getName()
+ " started making Ladoos with currently "
+ (ob.buffer++) + " ladoos in plate");
try {
Thread.sleep(0); // 1 sec time taken to make a ladoo
ob.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized (ob) {
try {
System.out.println("Plate is full, cook will wait ");
ob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void run() {
while (true) {
produce();
}
}
这是调用的主要方法,只是为了理解观众
public static void main(String[] args) {
Buffer b = new Buffer(0);
Producer p = new Producer(b);
Consumer c = new Consumer(b);
Thread producer = new Thread(p, "Cook");
Thread consumer = new Thread(c, "Bheem");
System.out.println("Main started");
// buffer size is taken as 5 max.
consumer.start(); // bheem takes 1.5 sec to finish a ladoo
/*try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
producer.start(); // cook takes 1 sec to prepare ladoo
输出
Plate is empty, bheem will wait for ladoos to serve
Cook started making Ladoos with currently 0 ladoos in plate
Bheem started eating Ladoos with currently 1 ladoos in plate
Plate is empty, bheem will wait for ladoos to serve
Cook started making Ladoos with currently 0 ladoos in plate
Bheem started eating Ladoos with currently 1 ladoos in plate
Plate is empty, bheem will wait for ladoos to serve
Cook started making Ladoos with currently 0 ladoos in plate
Bheem started eating Ladoos with currently 1 ladoos in plate
Plate is empty, bheem will wait for ladoos to serve
Cook started making Ladoos with currently 0 ladoos in plate
Bheem started eating Ladoos with currently 1 ladoos in plate
Cook started making Ladoos with currently 0 ladoos in plate
Cook started making Ladoos with currently 1 ladoos in plate
Cook started making Ladoos with currently 2 ladoos in plate
Cook started making Ladoos with currently 3 ladoos in plate
Cook started making Ladoos with currently 4 ladoos in plate
Plate is full, cook will wait
Plate is empty, bheem will wait for ladoos to serve
当消费者拿走最后一个 ladoo 时,是什么阻止了您的生产者完全填满盘子并调用最后一个 notify()
在 消费者设法调用 wait()
?同样,当盘子变满时,是什么阻止了消费者在生产者进入 wait()
之前拿走最后一个 ladoo 并调用最后一个 notify()
?
如果其他线程没有等待接收通知,则对 o.notify()
的调用无任何作用。也就是说对象o
不记得有通知过
我有一个代码,其中实现 Runnable 的两个线程 classes 是 运行 并且共享 class 缓冲区的公共对象。
虽然我在我的知识范围内正确地使用了同步块和 wait()
和 notify()
方法,但是当我在 try/catch 块中使用 Thread.sleep(0)
休眠线程时,在一些被接受的输出结果之后,它陷入僵局。
当我用 1000 毫秒 Thread.sleep(1000)
休眠线程 Cook 和用 3000 毫秒 Thread.sleep(3000)
这是线程中常见的生产者-消费者场景,我故意将消费者置于生产者之上。
P.S。 - 我已经给出了从最后一个修剪的 output。实际产量相当大。
以下代码在 Bheem class
public void consume() {
while (ob.buffer >= 1) {
synchronized (ob) {
System.out.println(Thread.currentThread().getName()
+ " started eating Ladoos with currently "
+ (ob.buffer--) + " ladoos in plate");
try {
Thread.sleep(0); // bheem takes 1.5 sec to eat
ob.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized (ob) {
try {
System.out
.println("Plate is empty, bheem will wait for ladoos to serve ");
ob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void run() {
while (true) {
consume();
}
}
这个在库克class
public void produce() {
while (ob.buffer < 5) {
synchronized (ob) {
System.out.println(Thread.currentThread().getName()
+ " started making Ladoos with currently "
+ (ob.buffer++) + " ladoos in plate");
try {
Thread.sleep(0); // 1 sec time taken to make a ladoo
ob.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized (ob) {
try {
System.out.println("Plate is full, cook will wait ");
ob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void run() {
while (true) {
produce();
}
}
这是调用的主要方法,只是为了理解观众
public static void main(String[] args) {
Buffer b = new Buffer(0);
Producer p = new Producer(b);
Consumer c = new Consumer(b);
Thread producer = new Thread(p, "Cook");
Thread consumer = new Thread(c, "Bheem");
System.out.println("Main started");
// buffer size is taken as 5 max.
consumer.start(); // bheem takes 1.5 sec to finish a ladoo
/*try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
producer.start(); // cook takes 1 sec to prepare ladoo
输出
Plate is empty, bheem will wait for ladoos to serve
Cook started making Ladoos with currently 0 ladoos in plate
Bheem started eating Ladoos with currently 1 ladoos in plate
Plate is empty, bheem will wait for ladoos to serve
Cook started making Ladoos with currently 0 ladoos in plate
Bheem started eating Ladoos with currently 1 ladoos in plate
Plate is empty, bheem will wait for ladoos to serve
Cook started making Ladoos with currently 0 ladoos in plate
Bheem started eating Ladoos with currently 1 ladoos in plate
Plate is empty, bheem will wait for ladoos to serve
Cook started making Ladoos with currently 0 ladoos in plate
Bheem started eating Ladoos with currently 1 ladoos in plate
Cook started making Ladoos with currently 0 ladoos in plate
Cook started making Ladoos with currently 1 ladoos in plate
Cook started making Ladoos with currently 2 ladoos in plate
Cook started making Ladoos with currently 3 ladoos in plate
Cook started making Ladoos with currently 4 ladoos in plate
Plate is full, cook will wait
Plate is empty, bheem will wait for ladoos to serve
当消费者拿走最后一个 ladoo 时,是什么阻止了您的生产者完全填满盘子并调用最后一个 notify()
在 消费者设法调用 wait()
?同样,当盘子变满时,是什么阻止了消费者在生产者进入 wait()
之前拿走最后一个 ladoo 并调用最后一个 notify()
?
如果其他线程没有等待接收通知,则对 o.notify()
的调用无任何作用。也就是说对象o
不记得有通知过