Java ArrayBlockingQueue中类型为Runnable的毒药丸

Java ArrayBlockingQueue中类型为Runnable的毒药丸,java,multithreading,Java,Multithreading,我有一个包含要执行的任务的阻塞队列: private final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(20); private final AtomicInteger isPoisingPill = new AtomicInteger(2); //two producers 每个提供程序在完成作业时,make:isPoisingPill.decrementAndGet() 但它并非在所有情况下

我有一个包含要执行的任务的阻塞队列:

private final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(20);
private final AtomicInteger isPoisingPill = new AtomicInteger(2); //two producers
每个提供程序在完成作业时,make:
isPoisingPill.decrementAndGet()

但它并非在所有情况下都有效。有时,当我们进入循环时,生产者将PoisingPill设置为false,程序挂起,因为操作
take()
正在等待队列中的元素,而不是,因为生产者已经完成。事实证明,避孕药应该直接放在队列中,并且在循环中已经检查是否相等。但是,如果队列只包含
Runnable
对象,我应该在那里放置什么呢


还有一种情况是,我有很多制片人。我们需要等待它们完成。

是的,毒药丸应该添加到包含任务的队列中。 您可以创建自己的类,扩展
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);
  }
}
int pillscont=0;
while(pillscont<2){
MyRunnable任务=queue.take();
if(task.isPoisonPill()){
++枕木;
}否则{
执行人提交(任务);
}
}

是的,应该将毒药丸添加到包含任务的队列中。 您可以创建自己的类,扩展
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);
  }
}
int pillscont=0;
while(pillscont<2){
MyRunnable任务=queue.take();
if(task.isPoisonPill()){
++枕木;
}否则{
执行人提交(任务);
}
}

Poising?你是说毒药吗?我是说:毒药起球?你是说毒药吗?我的意思是:毒药在这种情况下,还有一个大问题。一个生产商将在另一个生产商之前发送毒丸,周期将结束,但第二个生产商仍在工作@所有安全的消费者只有在获得与生产商相同数量的药片时才应该停止服用。所以,在你的情况下,消费者应该停止后,收到两个毒药pillsOk,我想是的!但是如何在一个周期内检查这个数字呢?不需要每个任务对象都携带一个布尔标志,也不需要编写额外的代码来测试它。毒丸只能是一个具有启动关机过程的
run()
方法的对象。@在这种特殊情况下,消费者应收到2颗毒丸才能停止工作。此外,任务生产者不应该知道任何关于任务消费者内部的信息。如果没有这些知识,很难启动关机过程。在这种情况下,还有一个大问题。一个生产商将在另一个生产商之前发送毒丸,周期将结束,但第二个生产商仍在工作@所有安全的消费者只有在获得与生产商相同数量的药片时才应该停止服用。所以,在你的情况下,消费者应该停止后,收到两个毒药pillsOk,我想是的!但是如何在一个周期内检查这个数字呢?不需要每个任务对象都携带一个布尔标志,也不需要编写额外的代码来测试它。毒丸只能是一个具有启动关机过程的
run()
方法的对象。@在这种特殊情况下,消费者应收到2颗毒丸才能停止工作。此外,任务生产者不应该知道任何关于任务消费者内部的信息。没有这些知识,很难启动关闭过程