java - 如何避免多生产者和消费者的饥饿?

标签 java multithreading producer-consumer blockingqueue

  1. 这里考虑 2 个生产者线程和 1 个消费者线程。
  2. 假设队列已满。
  3. 由于队列已满,两个生产者线程进入等待状态。
  4. 消费者线程从队列中获取元素并notifyAll,因此一个生产者线程添加元素并退出,另一个生产者线程保持等待状态,另一个生产者线程再次添加元素并退出。
  5. 因此,如果您观察到,一个线程很可能始终处于等待状态。

如何避免这种情况?

import java.util.LinkedList;
import java.util.List;

interface BlockingQueueCustom<E> {

      void put(E item)  throws InterruptedException ;

      E take()  throws InterruptedException;
}

class LinkedBlockingQueueCustom<E> implements BlockingQueueCustom<E> {

    private List<E> queue;
    private int maxSize; // maximum number of elements queue can hold at a time.

    public LinkedBlockingQueueCustom(int maxSize) {
        this.maxSize = maxSize;
        queue = new LinkedList<E>();
    }

    public synchronized void put(E item) throws InterruptedException {

         while(queue.size() == maxSize) {
            this.wait();
        }

        queue.add(item);
        this.notifyAll();
    }

    public synchronized E take() throws InterruptedException {

        while(queue.size() == 0) {
            this.wait();
        }

        this.notifyAll();
        return queue.remove(0);

    }

}

public class BlockingQueueCustomTest {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueueCustom<Integer> b = new LinkedBlockingQueueCustom<Integer>(10);
        System.out.println("put(11)");
        b.put(11);
        System.out.println("put(12)");
        b.put(12);
        System.out.println("take() > " + b.take());
        System.out.println("take() > " + b.take());

    }
}

最佳答案

使用waitnotify已经过时since 2005因为它的功能有限。

对于您的具体问题,我真的建议重构您的解决方案以使用 Java Semaphore class 。您将看到可以设置公平参数。此参数将确保分配以 FIFO 方式完成,以便一旦您的一个线程获得许可并将数据放入队列中,当再次阻塞时,它会被带到行尾(因此,第二个线程将获得优先权)。

希望这有帮助。

关于java - 如何避免多生产者和消费者的饥饿?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50935418/

相关文章:

java - 更改单行 if 语句的 Eclipse 格式

java - kafka MockConsumer 抛出异常错误 java.lang.IllegalStateException : Subscription to topics, 分区和模式是互斥的

c - 信号量的有效使用?

java - 使用 ThreadPoolExecutor 的同步任务生产者/消费者

java - 分配空值或更改值之间有什么区别?

Java 应用程序事件 : Difference between @EventListener annotation and ApplicationListener interface

java - 能够执行由另一个线程发送的特定作业的线程的任何可用设计模式?

python - 更新多线程 PyQT 中的 GUI 元素

C++ 单生产者多消费者程序偶尔崩溃

task-parallel-library - TPL 默认构造函数 BufferBlock : Value of DataFlowBlockOptions