为了账号安全,请及时绑定邮箱和手机立即绑定

ArrayBlockingQueue 中 Runnable 类型的毒丸

ArrayBlockingQueue 中 Runnable 类型的毒丸

HUWWW 2021-10-17 15:58:36
我有一个阻塞队列,其中包含要执行的任务:private final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(20);private final AtomicInteger isPoisingPill = new AtomicInteger(2); //two producers还有一个消费者:while (isPoisingPill.get() != 0) {     processExecutor.submit(this.kpiData.take()));}每个提供者在完成一项工作时,使: isPoisingPill.decrementAndGet();但它并不适用于所有情况。有几次我们进入循环,生产者把PoisingPill置为false,程序挂了,因为操作take()在等待队列中的元素,而事实并非如此,因为生产者已经完成了。事实证明,药丸应该直接放在队列中,并且在循环中已经检查了是否相等。但是如果队列只包含Runnable对象,我应该在那里放什么?还有一种情况是我有很多制作人。我们需要等待它们完成。
查看完整描述

1 回答

?
蓝山帝景

TA贡献1843条经验 获得超7个赞

是的,毒丸应该与任务一起添加到队列中。您可以创建自己的类扩展Runnable并具有布尔标志


public class MyRunnable implements Runnable {

  private boolean posionPill = false;


  public Boolean isPosionPill() {

    return poisonPill;

  }

  ..... // your other stuff

}

当您take()在开始执行之前调用检查该标志时Runnable


另一种选择是有


public static final Runnable POISON_PILL = new Runnable() { 

  public void run(){}

};

在您的代码中的某处并将该静态对象添加到队列中,然后take()将队列中的对象与该常量进行比较


而在消费者中,你需要做这样的事情


int pillsCount = 0;

while (pillsCount < 2) {

  MyRunnable task = queue.take();

  if (task.isPoisonPill()) {

    ++pillsCount;

  } else {

    executor.submit(task);

  }

}


查看完整回答
反对 回复 2021-10-17
  • 1 回答
  • 0 关注
  • 182 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信