2010-05-07 82 views
3

是否有一个带有阻塞队列的实现,但有一个最大大小限制。当队列大小达到给定的最大大小时,不会阻塞'put',它会删除head元素并插入它。所以把不被阻塞(),但采取()是。阻塞'take()'的队列实现,但带有驱逐策略

一个用法是,如果我有一个非常缓慢的消费者,系统不会崩溃(内存不足),而这些消息将被删除,但我不想阻止生产者。

股票交易系统的一个例子。当您在股票交易/报价数据上涨时,如果您没有消费数据,您希望自动抛弃旧的股票交易/报价。

回答

1

目前在Java中没有一个线程安全的队列,它将执行你正在寻找的任务。但是,有一个BlockingDequeue(双端队列),您可以编写一个包装器,您可以从头部和尾部随意取出。

这个类,类似于BlockingQueue,是线程安全的。

1

ThreadPoolExecutor提供了几种策略。在javadoc中搜索“AbortPolicy”。如果需要,您也可以实施自己的策略。也许Discard是类似于你想要的。我个人认为CallerRuns是你想在大多数情况下。

我认为使用这些是一个更好的解决方案,但是如果你绝对想在队列中实现它,我可能会通过组合来实现。也许使用LinkedList或其他东西,并用synchronize关键字包装它。

编辑:(一些澄清..) “执行者”基本上是一个线程池与阻塞队列相结合。这是在java中实现生产者/消费者模式的推荐方式。这些图书馆的作者提供了几种策略来处理像你提到的问题。如果您有兴趣,here是专门解决OOME问题的另一种方法(源代码是特定于框架的,不能按原样使用)。

+0

AbortPolicy在ThreadPool正在关闭时使用,因此它需要排空排队的任务。我想要的是一个最大大小的队列,当您添加新任务时会弹出第一条消息。 另外,你附加的netty样本被'封锁'了。我所寻找的实现并未被阻止,而是排在队列头上。 – mjlee 2010-05-07 05:06:59

+0

@mjlee:那么,建议的搜索只是为了让您更容易找到该部分。我不打算使用该政策。我想我会提供一个更通用的答案。如果你想要什么你特别想要的,我建议实施一个自定义策略。您可以使用Deque作为队列实现,以便您可以从头部弹出。就我个人而言,我觉得它虽然从头上弹出很奇怪。为什么不简单地丢弃?没有根本的区别,而且更简单,更简单。它已经被其他人实施。 – 2010-05-07 05:12:15

+0

btw,不,AbortPolicy不用于排除任务。当制片人速度太快时,放弃这个策略是一种策略! – 2010-05-07 06:11:59