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

时间:2018-06-19 19:10:11

标签: java multithreading producer-consumer blockingqueue

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

如何避免这种情况?

scale_x_log10()

2 个答案:

答案 0 :(得分:2)

since 2005已过时,waitnotify的使用已经过时,因为它只能做些限制。

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

希望这会有所帮助。

答案 1 :(得分:1)

有几种选择。一种是使用标准的ArrayBlockingQueue调用两个参数构造函数。在这种情况下,队列将按FIFO顺序处理线程,而生产者将按照尝试将元素放入队列的顺序在队列中添加元素。

/**
 * Creates an {@code ArrayBlockingQueue} with the given (fixed)
 * capacity and the specified access policy.
 *
 * @param capacity the capacity of this queue
 * @param fair if {@code true} then queue accesses for threads blocked
 *        on insertion or removal, are processed in FIFO order;
 *        if {@code false} the access order is unspecified.
 * @throws IllegalArgumentException if {@code capacity < 1}
 */
public ArrayBlockingQueue(int capacity, boolean fair) {...}

另一种选择是使用ReentrantReadWriteLock并启用公平参数,而不要使用synchronized块。

/**
 * Creates a new {@code ReentrantReadWriteLock} with
 * the given fairness policy.
 *
 * @param fair {@code true} if this lock should use a fair ordering policy
 */
public ReentrantReadWriteLock(boolean fair) {...}

这是一个如何使用synchronizedReentrantReadWriteLock块转换为代码的示例:https://javarevisited.blogspot.com/2015/06/java-lock-and-condition-example-producer-consumer.html