【问题标题】:Exists an implementation like SynchronousQueue with capacity?是否存在像 SynchronousQueue 这样的具有容量的实现?
【发布时间】:2012-08-10 16:13:57
【问题描述】:

在 Java 应用程序中,我需要从 Socket 连接读取项目(原因未在此处进一步说明)

  1. 要由单个线程处理的输入项,以便保留它们的顺序。
  2. 在处理之前要缓冲的输入项目,以便在其他项目仍在处理时可以从套接字读取新项目。
  3. 只要缓冲区已满,读取线程就会被阻塞

所以实际上我想使用单个工作线程来处理从套接字接收到的缓冲项。还有一个合适的队列作为工作线程和读取线程之间的缓冲区,这将是一种公平的SynchronousQueue,具有 FIFO 容量。

所需的队列应该表现得像 ArrayBlockingQueueLinkedBlockingQueue,但容量未满,且类似于 SynchronousQueue,表示满时

  1. 队列上的put只会在队列满时阻塞线程
  2. 队列上的take只会在队列为空时阻塞线程
  3. 满队列上的take 将为调用者提供下一个 FIFO 元素,并取消阻塞并插入来自在 put 操作中等待的下一个线程的元素
  4. 空队列上的put 要么将元素移交给在poll 操作中等待的线程,要么将其插入

有没有类似的已知实现,还是我必须推出自己的?

【问题讨论】:

  • ArrayBlockingQueue有什么区别?
  • 您能说明这与ArrayBlockingQueue 有何不同吗?如果没有可用的线程,带有 SynchronousQueue 的 ExecutorService 也不会阻塞。
  • @PeterLawrey 是的,你是对的! ThreadPoolExecutor 实际上没有使用put 而是offer。因此,将ThreadPoolExecutor 与单线程一起使用与SynchronousQueue 一起使用似乎没有任何意义。我在文中澄清说,我必须使用自己的工作线程重复 poll 队列中的项目。
  • @你是对的!我对BlockingQueue 提供的插入/删除项目的不同方法感到困惑:/ 似乎这正是我所需要的。任何第一个写答案的人都会被接受;)
  • 顺便说一句,在多个线程上处理缓冲区对象并不难。如果每个线程在被推入队列之前都获得了递增的序列号,则可以在处理完成时对来自多个线程的输出重新排序。需要一个容器来容纳等待早期对象到达的对象。

标签: java multithreading queue


【解决方案1】:

一个答案不仅仅是试图从那些建议 ArrayBlockingQueue 的海报中窃取积分:

两个 ArrayBlockingQueue。一个充当“池队列” - 在启动时填充缓冲区对象。另一个用于处理线程等待工作。

套接字线程必须先从池中获取一个缓冲区,然后才能将其加载数据并将其排队到处理线程。处理线程在处理完数据后,最终必须将“使用过的”对象返回到池中。如果池为空,则套接字线程将阻塞它,直到返回一些缓冲区。

这提供了与有界处理队列相同的流控制,但还有一个额外的优点是可以避免缓冲区上的 GC。

【讨论】:

    猜你喜欢
    • 2020-02-17
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多