这有一个名字,但我不知道它是什么,所以很难谷歌。
我要找的是java并发实用程序中的一些东西,它是一对队列、生产者使用的“挂起”队列和消费者使用的“处理”队列,其中使用者可以原子地交换队列。如果以这种方式使用(1个生产者线程,1个使用者线程),那么单个队列不需要是threadsafe,只需要对它们的引用。
我知道我以前在某个地方见过,我可能可以自己拼凑出这样的东西,但如果它已经存在,我宁愿使用它。
编辑:我想我要找的原语是一对原子引用,可以用原子交换。(&我可以自己添加队列。)
编辑2: @Alex回答了一个唠叨的问题,那就是我在想什么,但却记不起来。然而,这并不能解决我的问题,因为这是一个线程屏障,我希望生产者不必阻止。
@sfossin关于交换对队列的引用的观点很好;我想要的是,消费者从队列中开始检索和处理项目的那一刻,所有的队列项都必须完成,而生产者之后不能添加任何项;生产者现在必须将项添加到另一个队列中。因此,配对/交换的原子引用集将无法工作。
(这有点像有两辆校车,其中一辆总是在等乘客,另一辆总是把它们送到别处。司机一开走,你就得上另一辆公共汽车。具有引用可以让生产者访问总线,即使它已经离开了,这是不允许的。)
我想我要做的是使用单个ConcurrentLinkedQueue,并将一个哨位值添加到队列中。这允许有多个生产者,而不仅仅是1。为了让使用者处理队列中的批项目,使用者等待队列中至少有1项,然后在队列末尾插入哨兵,然后删除项直到前哨被移除。然后消费者在批次之间做它必须做的任何事情。这就是我想要的行为。
它不一定需要有保证的非阻塞方法(锁定或synchronized方法是选项),但是如果有一种简单的方法来设计它,那么这在我的应用程序中是首选的。
发布于 2009-03-11 20:11:26
交换器
发布于 2009-03-11 20:14:59
读取器/写入器锁定队列,可能是一个更好的主意。因为,否则您将不得不原子地复制到本地队列。
因为您有一个同步问题,如果您交换了引用,而其中一个正在读取/删除或写入。
RWLock将允许多个消费者/生产者。
有什么原因,为什么你想远离RWLocks?
与任何锁定一样,锁应保持尽可能短的时间,以防止饥饿。
或者用这样的东西来交换数据。每个线程都有自己的队列。
class LockedQueue
{
private final List<Data> q = new ArrayList<Data>();
private final Lock lock = new ReentrantLock();
public void get( List<Data> consumerQ ) {
if( lock.tryLock() ) { try { consumerQ .addAll( q ); q.clear(); } finally { lock.unlock(); }}
}
public Data put( List<Data> producerQ ) {
if( lock.tryLock() ) { try { return q.addAll( producerQ ); producerQ .clear(); } finally { lock.unlock(); }}
}
public void clear() {
lock.lock(); try { q.clear(); } finally { lock.unlock(); }
}
}使用使用者调用get(),当每个循环为空或结束时,在添加了那么多项或时间或.
发布于 2009-03-11 19:38:09
没有像您描述的那样具有双队列的数据结构,但是并发使用有很多不同的队列可供选择。
你描述的问题很常见,我也希望能找到一个。也许在Java 1.7中。
https://stackoverflow.com/questions/636011
复制相似问题