分布式任务队列中的并发(生产者/消费者)

时间:2014-05-27 12:43:02

标签: java multithreading concurrency distributed task-queue

我的应用程序(Java)随机生成一些任务,并由分布式后台线程消耗异步。

我目前没有像ZooKeeper这样的分布式锁定解决方案。 我没有任何第三方消息队列。

我使用数据库作为任务队列,消耗的结果也保存在数据库中,所有消费者/生产者共享访问权。

我有一些像这样的代码:

消费者:

while(true) {
  // block the thread and wait from producer's notify
  // my producers would produce MANY work items but only notify each consumer ONCE.
  waitProducer();

  // consume the queue
  while(database.queueNotEmpty()) {
    // consume each work item and remove from database queue
    consumeAll();
  }
}

制片:

for(...) {
  database.enqueue(work[i]);
}
// notify all consumers
notifyAllConsumer();

显然上面的代码有并发错误。我有3个问题:

1.如何避免分布式消费者消耗相同的任务? (关于这一行:" consumeAll()") 或减少重复的计算。多次消耗一项任务不会成为一个错误,但在我的情况下效率会降低。

2.如何避免队列不为空但没有消费者活跃?顺序是: 一个消费者和一个一个生产者样本:

  • Consumer:while(database.queueNotEmpty())// queue为空,break while循环
  • 制作人:database.enqueue(work [i]); //生成任务
  • 制片人:notifyAllConsumer(); //通知消费者,但是 它已经活跃了
  • 消费者:waitProducer(); //挂起主题但仍有工作要做

3.这个问题的最佳做法是什么?特别是在纯java中。 是第三方消息队列还是类似zookeeper的东西? 减少锁定或无锁定是首选;在我的情况下,有效率更倾向于正确。

谢谢!

1 个答案:

答案 0 :(得分:0)

我建议你在这种情况下使用LinkedBlockingQueue

LinkedBlockingQueue tutorial

您可以使用take()/ put()方法,如果您想等待timelimit,可以使用offer(),poll()和peek()。

我也在类似的问题中使用过它。