以原子方式将第一个元素添加到ConcurrentLinkedQueue

时间:2012-07-25 16:53:53

标签: java multithreading concurrency lock-free

我想以原子ConcurrentLinkedQueue方式使用lock-free

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

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

迪特。

2 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:1)

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