3

我想以原子无锁方式使用ConcurrentLinkedQueue

几个并发线程将事件推送到队列中,其他一些线程将处理它们。队列未绑定,我不希望任何线程等待或被锁定。然而,阅读部分可能会注意到队列变空了。在无锁实现中,读取线程不能阻塞,而只会结束其任务并继续执行其他任务(即作为 ExecutorService)。因此,将第一个新事件推入空队列的写入者必须意识到它并应该重新启动读取器(即通过向 ExecutorService 提交新的 Runnable)来处理队列。提交第二个或第三个事件的任何其他线程都不会关心,因为它们可能会假设某些读者已经准备/提交。

不幸的是,ConcurrentLinkedQueue 的add()方法总是返回 true。在添加事件之前或之后询问队列是否 isEmpty() 将无济于事,因为它不是原子的。我应该使用一些额外的 AtomicInteger 来监控队列大小()还是有一些更智能的解决方案?

迪特。

4

2 回答 2

2

我不太明白你为什么不ExecutorService直接使用它。它在BlockingQueue内部使用 a 并处理所有信令本身。

// open ended thread pool
ExecutorService threadPool = Executors.newFixedThreadPool(1);
for (Job job : jobsToDo) {
    threadPool.submit(new MyJobProcessor(job));
}

除非您有充分的理由,否则我不会自己重写相同的逻辑。

如果您试图以某种方式使用休眠线程,我强烈建议您不要打扰。线程相对便宜,因此分配一个线程来处理您的排队任务很好。重复使用线程是不必要的,对我来说似乎是过早的优化。

于 2012-07-25T17:22:01.213 回答
1

使用 ofAtomicInteger来解决提交争用比锁定或synchronized阻塞更有效。

于 2012-07-26T02:45:38.987 回答