- 这里考虑 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());
}
}
最佳答案
使用wait
和notify
已经过时since 2005因为它的功能有限。
对于您的具体问题,我真的建议重构您的解决方案以使用 Java Semaphore class 。您将看到可以设置公平参数。此参数将确保分配以 FIFO 方式完成,以便一旦您的一个线程获得许可并将数据放入队列中,当再次阻塞时,它会被带到行尾(因此,第二个线程将获得优先权)。
希望这有帮助。
关于java - 如何避免多生产者和消费者的饥饿?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50935418/