Tag: blockingqueue

BlockingQueue的drainTo()方法的线程安全性

BlockingQueue的文档说批量操作不是线程安全的,尽管它没有明确提到方法drainTo()。 BlockingQueue实现是线程安全的。 所有排队方法都使用内部锁或其他forms的并发控制以primefaces方式实现其效果。 但是,除非在实现中另有说明,否则批量收集操作addAll,containsAll,retainAll和removeAll不一定以primefaces方式执行。 因此,例如,在仅添加c中的一些元素之后,addAll(c)可能会失败(抛出exception)。 drainTo()方法的文档指定无法以线程安全的方式修改BlockingQueue元素所用的集合。 但是,它没有提到有关drainTo()操作是线程安全的任何事情。 从此队列中删除所有可用元素,并将它们添加到给定集合中。 此操作可能比重复轮询此队列更有效。 尝试向集合c添加元素时遇到的故障可能导致在抛出关联的exception时元素既不在集合中,也不在集合中。 尝试将队列排放到自身会导致IllegalArgumentException。 此外,如果在操作正在进行时修改指定的集合,则此操作的行为是不确定的。 那么,drainTo()方法是线程安全的吗? 换句话说,如果一个线程在阻塞队列上调用了drainTo()方法,而另一个线程在同一个队列上调用了add()或put(),那么两个操作结束时队列的状态是否一致?

生产者/消费者工作队列

我正在努力实现我的处理管道的最佳方法。 我的制作人将作品提供给BlockingQueue。 在消费者方面,我轮询队列,包装我在Runnable任务中获得的内容,并将其提交给ExecutorService。 while (!isStopping()) { String work = workQueue.poll(1000L, TimeUnit.MILLISECONDS); if (work == null) { break; } executorService.execute(new Worker(work)); // needs to block if no threads! } 这不理想; 当然,ExecutorService有自己的队列,所以真正发生的事情是我总是完全耗尽工作队列并填充任务队列,随着任务的完成,队列会慢慢排空。 我意识到我可以在生产者端排队任务,但我真的不愿意这样做 – 我喜欢我的工作队列的间接/隔离是愚蠢的字符串; 这真的不是制片人的任何事情会发生在他们身上。 迫使生产者对Runnable或Callable进行排队会打破抽象,恕我直言。 但我确实希望共享工作队列代表当前的处理状态。 如果消费者没有跟上,我希望能够阻止生产者。 我喜欢使用Executors,但我觉得我正在与他们的设计作斗争。 我可以部分喝Kool-ade,还是我必须吞下它? 我是否在拒绝排队任务方面做错了? (我怀疑我可以设置ThreadPoolExecutor来使用1任务队列并覆盖它的执行方法来阻止而不是拒绝队列满,但这感觉很糟糕。) 建议?