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

2024-03-09

我想用一个并发链接队列 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html在原子的无锁 http://en.wikipedia.org/wiki/Non-blocking_algorithm manner:

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

不幸的是add() http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html#add%28E%29ConcurrentLinkedQueue 方法始终返回 true。在添加事件之前或之后询问队列是否 isEmpty() 没有帮助,因为它不是原子的。 我应该使用一些额外的 AtomicInteger 来监视队列大小()还是有一些更智能的解决方案?

Dieter.


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

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以原子方式将第一个元素添加到 ConcurrentLinkedQueue 的相关文章

随机推荐