簡體   English   中英

生產者/消費者死鎖多線程Java

[英]Producer/Consumer deadlock multithreading Java

我正在嘗試使用多線程解決Java中的Producer / Consumer問題,但是我一直陷於僵局,我不知道為什么。

BoundedBuffer.java

public class BoundedBuffer {
    private final int[] buffer;
    private final int N;
    private int in = 0;
    private int out = 0;
    private int itemCount = 0;

    public BoundedBuffer(int size) {
        N = size + 1; 
        buffer = new int[N];
    }

    public void insert(Producer producer, int item) {
        synchronized (producer) {
            while ( (in + 1) % N == out) {
                try {
                    producer.wait();
                } catch (InterruptedException e) {}
        }
        buffer[in] = item;
        in = (in + 1) % N;
        itemCount++;
    }

    public int remove(Consumer consumer) {
        synchronized (consumer) {
            while (in == out) {
                try {
                    consumer.wait();
                } catch (InterruptedException e) {}
            }

            int item = buffer[out];
            buffer[out] = null;
            out = (out + 1) % N;
            itemCount--;

            return item;
        }
    }
}

Producer.java

public class Producer extends Thread {
    private int total = 0;
    private BoundedBuffer buffer;
    private int uniqueItem = 0;

    public Producer(int total, BoundedBuffer b) {
        this.total = total;
        this.buffer = b;
    }

    public void run() {
        for (int i = 0; i < quota; i++) {
            try {
                Thread.sleep((int)(Math.random() * 100));
            } catch (InterruptedException e) {}
            buffer.insert(this, uniqueItem++);
            this.notifyAll();
        }
    }
}

Consumer.java

public class Consumer extends Thread {
    private int total = 0;
    private BoundedBuffer buffer;

    public Consumer(int total, BoundedBuffer b) {
        this.total = total;
        this.buffer = b;
    }

    public void run() {
        for (int i = 0; i < total; i++) {
            try {
                Thread.sleep((int)(Math.random() * 100));
            } catch (InterruptedException e) {}         
            buffer.remove(this);
            this.notifyAll();
        }
    }
}

這段代碼將運行一段時間,當我進行調試設置時(“此生產者正在嘗試插入此項目...”),我看到了一個不錯的模式,但是不時出現此錯誤:

Exception in thread "Thread-2" java.lang.IllegalMonitorStateException
    at java.lang.Object.notifyAll(Native Method)
    at Consumer.run(Consumer.java:19)

然后在那之后的一段時間里我發生了死鎖。

我認為我的問題是由於要同步的密鑰( producerconsumer實例)造成的。 我不確定我還能在什么方法上進行同步,而這最讓我感到困擾。 我相信我可以為每個消費者/生產者共享一個密鑰,但是我不確定這將如何工作。

您應該在BoundedBuffer本身上進行同步,並在已同步的塊內使用wait來釋放鎖,然后等待另一個線程通知正在休眠的線程。

本教程中有一個完整的示例: https : //docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html

另外,請注意,您現在可以使用BlockingQueue以更簡單的方式實現Consumer-Producer模式。

在這里,您具有BlockingQueue的文檔,其中顯示了更簡單的Consumer-Producer實現: http : //docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html

暫無
暫無

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

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