合并两个队列

  • 为了避免无限阻塞,不应该在线程合并发生时从队列中读取。
  • 为了避免同步或无限地等待其中一个队列而其他队列有数据,从队列中读取不应该发生在同一个线程上。

让我们从定义和填充两个队列开始:

q1 = Queue.new
q2 = Queue.new
(1..100).each { |e| q1 << e }
(101..200).each { |e| q2 << e }

我们应该创建另一个队列并将数据从其他线程推入其中:

merged = Queue.new

[q1, q2].map do |q|
  Thread.new do
    loop do
      merged << q.pop
    end
  end
end

如果你知道你可以完全消耗两个队列(消耗速度高于生产,你将不会用完 RAM)有一个更简单的方法:

merged = Queue.new
merged << q1.pop until q1.empty?
merged << q2.pop until q2.empty?