在多线程中检测到不合理的死锁 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不记得有通知过