带有阻塞“take()”的队列实现但有驱逐政策
是否有一个带有阻塞队列的实现,但受最大大小限制。当队列的大小达到给定的 max-size 时,它不会阻塞“put”,而是删除头元素并插入它。所以 put 不会被阻塞,而 take() 会被阻塞。
一种用法是,如果我的消费者非常慢,系统不会崩溃(内存不足),而是这些消息将被删除,但我不想阻止生产者。
股票交易系统就是一个例子。当您的股票交易/报价数据激增时,如果您尚未消耗数据,您希望自动丢弃旧的股票交易/报价。
Is there an implementation with a blocking queue for take but bounded by a maximum size. When the size of the queue reaches a given max-size, instead of blocking 'put', it will remove the head element and insert it. So put is not blocked() but take() is.
One usage is that if I have a very slow consumer, the system will not crash ( runs out of memory ) rather these message will be removed but I do not want to block the producer.
An example of this would stock trading system. When you get a spike in stock trade/quote data, if you haven't consumed data, you want to automatically throw away old stock trade/quote.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
目前 Java 中没有线程安全队列可以满足您的需求。但是,有一个 BlockingDequeue(双端队列),您可以编写一个包装器,您可以在其中自由地从头部和尾部获取。
该类与 BlockingQueue 类似,是线程安全的。
There currently isnt in Java a thread-safe queue that will do what you are looking for. However, there is a BlockingDequeue (Double Ended Queue) that you can write a wrapper in which you can take from the head and and tail as you see freely.
This class, similar to a BlockingQueue, is thread safe.
ThreadPoolExecutor 中提供了几种策略。在此 javadoc。如果您愿意,您也可以实施自己的政策。也许
Discard
与您想要的类似。我个人认为在大多数情况下CallerRuns
是您想要的。我认为使用这些是一个更好的解决方案,但如果你绝对想在队列中实现它,我可能会通过组合来实现。也许使用
LinkedList
或其他东西,并用synchronize
关键字包装它。编辑:(一些澄清..)
“执行器”基本上是一个线程池与阻塞队列的结合。这是在 java 中实现生产者/消费者模式的推荐方法。这些库的作者提供了几种策略来应对您提到的问题。如果您有兴趣,这里是另一种专门解决 OOME 问题的方法(源代码是特定于框架的,不能按原样使用)。
Several strategies are provided in ThreadPoolExecutor. Search for "AbortPolicy" in this javadoc . You can also implement your own policy if you want. Perhaps
Discard
is similar to what you want. Personally I thinkCallerRuns
is what you want in most cases.I think using these is a better solution, but if you absolutely want to implement it at the queue, I'd probably do it by composition. Perhaps use a
LinkedList
or something and wrap it withsynchronize
keyword.EDIT:(some clarifications..)
"Executor" is basically a thread pool combined with a blocking queue. It is the recommended way to implement a producer/consumer pattern in java. The authors of these libraries provides several strategies to cope with issues like you mentioned. If you are interested, here is another approach to specifically address the OOME issue (the source is framework specific and can't be used as is).