生产者/消费者死锁多线程Java

时间:2015-09-28 02:04:27

标签: java multithreading deadlock producer-consumer

我正在尝试使用多线程解决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();
        }
    }
}

此代码将运行一段时间,当我有调试集时(&#34;此生产者正试图插入此项...&#34;)我看到一个很好的模式,但不时出现我收到这个错误:

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

然后我在那之后发生了一段时间的死锁。

我认为我的问题是由于我正在同步的密钥producerconsumer实例。我不知道还有什么我可以同步这个方法,这就是最让我感到困惑的事情。我相信我可以为每个消费者/制作人分享一把钥匙,但我不确定这是怎么回事。

1 个答案:

答案 0 :(得分:3)

您应该在BoundedBuffer本身上进行同步,并在synchronized块中使用wait来释放锁定并等待另一个线程通知睡眠的那个。

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

此外,请注意您现在可以使用BlockingQueue以更简单的方式实现消费者 - 生产者模式。

这里有BlockingQueue的文档,显示了更简单的Consumer-Producer实现: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html

相关问题