我有一个多线程应用程序,它有一个生产者线程和几个消费者线程。 数据存储在共享线程安全集合中,并在缓冲区中有足够数据时刷新到数据库。
来自javadocs -
BlockingQueue<E>
一个队列,它还支持在检索元素时等待队列变为非空的操作,并在存储元素时等待队列中的空间可用。
take()
检索并删除此队列的头部,必要时等待,直到元素可用为止。
我的问题 -
- 是否有另一个具有E [] take(int n)方法的集合?即阻塞队列等待直到元素可用。我想要的是 应该等到100或200个元素可用。
- 或者,是否有其他方法可用于解决问题而无需轮询?
醇>
答案 0 :(得分:2)
drainTo
方法并不是您正在寻找的方法,但它是否符合您的目的?
修改的
您可以使用take
和drainTo
的组合来实现性能稍高的批量阻止.min:
public <E> void drainTo(final BlockingQueue<E> queue, final List<E> list, final int min) throws InterruptedException
{
int drained = 0;
do
{
if (queue.size() > 0)
drained += queue.drainTo(list, min - drained);
else
{
list.add(queue.take());
drained++;
}
}
while (drained < min);
}
答案 1 :(得分:2)
我认为唯一的方法是扩展BlockingQueue
的某些实现或使用take
创建某种实用方法:
public <E> void take(BlockingQueue<E> queue, List<E> to, int max)
throws InterruptedException {
for (int i = 0; i < max; i++)
to.add(queue.take());
}
答案 2 :(得分:1)
我不确定标准库中是否有类似的类具有take(int n)
类型方法,但您应该能够包装默认的BlockingQueue
以添加该功能而不会有太多麻烦,不要你觉得呢?
备选方案是触发一个操作,在该操作中将元素放入集合中,由此设置的阈值将触发刷新。
答案 3 :(得分:1)
所以这应该是一个线程安全的队列,让你阻止获取任意数量的元素。我们欢迎更多的目光来验证线程代码是否正确。
package mybq;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class ChunkyBlockingQueue<T> {
protected final LinkedList<T> q = new LinkedList<T>();
protected final Object lock = new Object();
public void add(T t) {
synchronized (lock) {
q.add(t);
lock.notifyAll();
}
}
public List<T> take(int numElements) {
synchronized (lock) {
while (q.size() < numElements) {
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
ArrayList<T> l = new ArrayList<T>(numElements);
l.addAll(q.subList(0, numElements));
q.subList(0, numElements).clear();
return l;
}
}
}