合併兩個佇列

  • 為了避免無限阻塞,不應該線上程合併發生時從佇列中讀取。
  • 為了避免同步或無限地等待其中一個佇列而其他佇列有資料,從佇列中讀取不應該發生在同一個執行緒上。

讓我們從定義和填充兩個佇列開始:

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?