Java中的线程安全队列和"master/worker"程序的模式/原则

mar*_*her 11 java algorithm queue multithreading data-structures

我有一个问题,我认为是经典的主/工模式,我正在寻求实施方面的建议.以下是我目前正在考虑的问题:

有一种全球性的"队列",它是一个"保持工作"的中心位置.据推测,这个队列将由一种"主"对象管理.线程将被生成以找到要做的工作,当他们找到要做的工作时,他们会告诉主要事物(无论是什么)"将其添加到要完成的工作队列".

主人,也许是间隔,将产生实际执行工作的其他线程.一旦线程完成其工作,我希望它通知主服务器工作已完成.然后,主服务器可以从队列中删除此工作.

我以前在Java中完成了大量的线程编程,但它们都先于JDK 1.5,因此我不熟悉处理这种情况的相应新API.我知道JDK7将有fork-join,这对我来说可能是一个解决方案,但我无法在这个项目中使用早期访问产品.

我认为问题是:

1)如何让"线程完成工作"与主人沟通,告诉他们他们的工作已经完成,主人现在可以从队列中删除工作

2)如何有效地保证工作只安排一次.例如,假设这个队列有一百万个项目,它想告诉一个工人"去做这100件事".什么是最有效的方法来保证当它为下一个工人安排工作时,它会得到"接下来的100件事"而不是"我已经安排的100件事"?

3)为队列选择适当的数据结构.我在这里的想法是,"寻找工作要做的线程"可能会发现不止一次做同样的工作,并且他们会向主人发送一条消息,说"这里的工作",并且主人会意识到工作已经已经安排好,因此应该忽略该消息.我想确保选择正确的数据结构,以便这种计算尽可能便宜.

传统上,我会在数据库中以有限状态机方式完成此任务,从开始到完成工作"任务".但是,在这个问题中,我不想使用数据库,因为队列的数量和波动性很大.另外,我想尽量保持它的重量轻.如果可以避免,我不想使用任何应用服务器.

很有可能我所描述的这个问题是一个众所周知的名称和一套公认的解决方案的常见问题,但我,我的低级非CS学位,不知道这叫什么(即请温柔).

感谢任何和所有指针.

Den*_*nov 7

据我所知,您需要ExecutorService.ExecutorService有

submit(Callable task)
Run Code Online (Sandbox Code Playgroud)

返回值的方法是Future.未来是一种阻碍从工人到主人沟通的方式.您可以轻松地扩展此机制以异步方式工作.是的,ExecutorService还像ThreadPoolExecutor一样维护工作队列.因此,在大多数情况下,您不需要为调度而烦恼.java.util.concurrent包已经有了线程安全队列的高效实现(ConcurrentLinked queue - nonblocking和LinkedBlockedQueue - blocking).