【问题标题】:BlockingQueue and putAllBlockingQueue 和 putAll
【发布时间】:2010-07-02 01:28:22
【问题描述】:

有人知道为什么 java 的 BlockingQueue 没有 putAll 方法吗?这种方法有问题吗?有什么好的方法可以解决这个问题而无需完全重新实现 BlockingQueue?

【问题讨论】:

    标签: java blockingqueue


    【解决方案1】:
    for (Item item : items) {
        queue.put(item);
    }
    

    3 行,不确定那是完全重新实现阻塞队列。

    我想它希望你把 1 一个 1 放在一个线程正在等待读取它的情况下,它们不会等待你完成所有的读取。

    【讨论】:

    • 我有一个 BlockingPriorityQueue 并希望将一组项目放入一个原子操作中。
    • 然后你可以围绕for循环做一个同步(队列)。但这并不是队列的真正用途(如果你接近容量,你可能会死锁你的程序)。如果 1 个原子操作将 100 个项目放入队列中......那么您的队列应该是一个 queue> 并且您应该在 100 个单位块中放置和检索项目。
    【解决方案2】:

    我在ArrayBlockingQueue 上发现了同样的问题。我们想要一些缺少的额外方法:

    • void putAll(Collection<? extends E> c) throws InterruptedException
    • int drainAtLeastOneTo(@OutputParam Collection<? super E> c) throws InterruptedException
    • int drainAtLeastOneTo(@OutputParam Collection<? super E> c, int maxElements) throws InterruptedException

    有些人提倡使用BlockingQueue&lt;List&lt;E&gt;&gt;,但这需要malloc'ing 列表。有时你想避免它。此外,这假设您希望生产者和消费者使用相同的“块”大小。

    关于耗尽:同样,您可能希望生产者和消费者的块大小不匹配。所以生产者可能会插入单个项目,但消费者会批量工作。 drainTo() 不会阻塞,所以 drainAtLeastOneTo() 是一个解决方案。

    最后,我们复制了ArrayBlockingQueue的默认impl,直接添加了方法。同样,一个缺点是您需要对具体类型进行操作,而不是接口BlockingQueue

    您也可以考虑使用著名的(臭名昭著的?)LMAX Disruptor,但该模型与标准的 BlockingQueue 完全不同,因为您无法控制何时消耗物品。

    【讨论】:

    • 好奇该实现是否在 github/SO 上的某个地方,您应该添加一个链接以供参考?谢谢!
    • 您是带着这个来到concurrency-interest 或OpenJDK core-libs-dev 邮件列表的吗?我很乐意阅读讨论。
    猜你喜欢
    • 2023-04-01
    • 2011-11-11
    • 2013-09-29
    • 2018-08-22
    • 2012-01-21
    • 2018-08-06
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多