ワーカースレッドの停止 (良い回答)

久々の「増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編」の第 8 章 Worker Thread の問題 8-6 (ワーカースレッドの停止)の悪い回答を Two-Phase Termination で書き直してみました。
Thread の raise メソッドを使えば Java の interrupt() の真似ができるようです。マニュアルしっかり読め>自分。

Rubyリファレンスマニュアル - Thread
raise([error_type,][message][,traceback])
そのスレッドで強制的に例外を発生させます。

以下、悪い回答から変更したメソッドのみ掲載します。例外クラスには Interrupt を流用してます。NamedThread モジュールに until_stop_thread メソッドと stop_thread メソッドを追加して、例外を使ったスレッド停止処理をカプセル化してみました。

module NamedThread
  def initialize(name)
    @name = name
    @thread = nil
    @terminated = false
  end
  def until_stop_thread
    until @terminated
      begin
        yield
      rescue Interrupt
        @terminated = true
      end
    end
  end
  def stop_thread()
    @terminated = true
    @thread.raise Interrupt
  end
end

class ClientThread
  include NamedThread
  def run()
    i = 0
    until_stop_thread do
      @channel.put_request(Request.new(Thread.current[:name], i))
      sleep rand(1000).to_f / 1000.0
      i += 1
    end
  ensure
    puts "#{Thread.current[:name]} is terminated"
  end
end

class WorkerThread
  include NamedThread
  def run()
    until_stop_thread { @channel.take_request.execute }
  ensure
    puts "#{Thread.current[:name]} is terminated"
  end
end