簡體   English   中英

在多線程Java中檢測到不合理的DeadLock

[英]Unreasonable deadLock detected in multithreading Java

我有一個代碼,其中兩個實現Runnable的線程類正在運行並共享Buffer類的公共對象。

雖然我在我所知范圍內正確使用了同步塊以及wait()notify()方法,但是當我在try / catch塊中使用Thread.sleep(0)休眠線程時,在某些可接受的輸出結果之后,它將進入死鎖狀態。

當我以1000ms的Thread.sleep(1000)睡眠線程Cook和以3000ms的Thread.sleep(3000)線程Bheem睡眠時,未檢測到問題

這是線程中常見的生產者-消費者方案,我有意將消費者置於生產者之上。

PS-我已將輸出從上一個調整為較小。 實際產量很大。

下面的代碼在Bheem類中

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();
        }
    }

這是廚師課

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 

當消費者采取最后一個方法時,是什么阻止您的生產者在消費者設法調用wait() 之前完全填充盤子並調用最后的notify() wait() 同樣,當盤子裝滿時,是什么阻止了消費者在生產者進入wait()之前接受最后的ladoo和調用最后的notify() wait()

如果某個其他線程沒有等待接收通知,則對o.notify()調用不會執行任何操作 也就是說,對象o不記得它已被通知。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM