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

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


    }

}


慕勒3428872
浏览 162回答 2
2回答

蝴蝶不菲

自2005年以来,wait和的使用notify已经过时,因为它只能做些限制。对于您的特定问题,我真的建议您重构解决方案以使用Java Semaphore类。您将看到可以设置公平性参数。此参数将确保以FIFO方式进行分配,以便一旦您的一个线程获得许可并将数据放入您的队列后,再次阻塞时,数据就被带到行尾(因此,第二个线程将获得优先权)。希望这可以帮助。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java