为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕勒3428872 2021-04-10 14:11:15
在这里考虑2个生产者线程和1个消费者线程。假设队列已满。由于队列已满,两个生产者线程进入等待状态。消费者线程从队列和notifyAll中获取元素,因此生产者线程中的一个添加元素并退出,另一个生产者线程保持等待状态,另一个生产者线程再次添加元素并退出。因此,如果您观察到,则有一个线程可能始终处于等待状态的机会。如何避免这种情况?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());    }}
查看完整描述

2 回答

?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

自2005年以来,wait和的使用notify已经过时,因为它只能做些限制。

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

希望这可以帮助。


查看完整回答
反对 回复 2021-04-14
  • 2 回答
  • 0 关注
  • 161 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信