我想以无原子锁的方式使用ConcurrentLinkedQueue:
几个并发线程将事件推送到队列中,其他一些线程将处理这些事件。队列未绑定,我不希望任何线程等待或被锁定。然而,阅读部分可能会注意到队列变空了。在无锁实现中,读取线程不能阻塞,而只会结束其任务并继续执行其他任务(即作为ExecutorService)。因此,将第一个新事件推入空队列的编写器必须意识到这一点,并应重新启动读取器(即,通过向ExecutorService提交新的Runnable)来处理队列。提交第二个或第三个事件的任何其他线程都不会在意,因为他们可能会认为一些读者已经准备好/提交了。
不幸的是,ConcurrentLinkedQueue的add()方法总是返回true。在添加事件之前或之后询问队列isEmpty()没有帮助,因为它不是原子的。我应该使用一些额外的AtomicInteger来监控队列大小()吗?或者有更聪明的解决方案吗?
Dieter。
我不太明白为什么不直接使用ExecutorService
。它在内部使用BlockingQueue
,并自行处理所有信令。
// open ended thread pool
ExecutorService threadPool = Executors.newFixedThreadPool(1);
for (Job job : jobsToDo) {
threadPool.submit(new MyJobProcessor(job));
}
除非你有充分的理由,否则我不会自己重写同样的逻辑。
如果你试图以某种方式利用休眠线程,我强烈建议你不要打扰。线程相对便宜,所以分配一个线程来处理排队的任务是可以的。重复使用线程是不必要的,对我来说似乎是过早的优化。
使用AtomicInteger
解决提交争用比锁定或synchronized
块更有效。
-
下面是一个如何用Java实现它的示例。
-
还有一种比ConcurrentLinkedQueue更有效的多生产者/单写入器队列结构。
-
将其用于actor实现的示例。
-
另一个例子。