阻止'take()'但具有驱逐策略的队列实现

时间:2010-05-07 04:07:13

标签: java collections concurrency

是否有一个带有阻塞队列的实现,但是以最大大小为限。当队列的大小达到给定的最大大小时,它将删除头元素并插入它,而不是阻塞'put'。所以put不是阻塞()而是take()是。

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

这样的例子就是股票交易系统。当您获得股票交易/报价数据的高峰时,如果您没有消费数据,您希望自动丢弃旧的股票交易/报价。

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:1)

目前Java中没有一个线程安全的队列可以满足您的需求。但是,有一个BlockingDequeue(双端队列),您可以编写一个包装器,您可以从头部和尾部自由地看到它。

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