RubyでSingletonパターン考察3・Mutexでマルチスレッド対応

はてなブックマークに追加はてなブックマーク Yahoo!ブックマークに登録 ニフティクリップに追加 Livedoor クリップに追加 BuzzurlにブックマークBuzzurlにブックマーク Twitterに投稿  

Singletonインスタンスが生成されているかどうかをif 条件文で判定して、Singletonパターンをマルチスレッドに対応させることを考えてみた。
その場合、Mutexクラスを使えばできそうだ・・・ということで、Threadクラスでスレッド生成、およびMutexクラスでスレッドセーフな排他的アクセス - Ruby入門勉強ルームで書いたようにMutexでSingletonインスタンスを取得するメソッドを、synchronizeで排他的アクセスにしてみた。


Mutexを用いたSingletonパターン

require 'thread'
require 'pp'
 
# スレッドのリストのうち、最初の3つを確認
def thread_list(threads)
  num = 0
  threads.each do |t|
    p t
    num += 1
    break if num == 3
  end
end
 
class Singleton
  @@singleton = nil
  @@mutex = Mutex.new
 
  # new をprivateにする
  private_class_method(:new)
 
  def self.singleton
    @@mutex.synchronize do
      if @@singleton == nil
        sleep 3
        @@singleton = new
      end
    end
    return @@singleton
  end
end
 
threads = []
for i in 1..3
  t = Thread.new do
    obj =  Singleton.singleton
    puts "#{obj.object_id}\n"
  end
  threads << t
end
pp Thread.list
 
threads.each do |th|
  th.join
end
pp Thread.list
thread_list(threads)

実行結果

[#<Thread:0x28f981c sleep>,
 #<Thread:0x28f9894 sleep>,
 #<Thread:0x28f9920 sleep>,
 #<Thread:0x284c748 run>]
21481110
21481110
21481110
[#<Thread:0x284c748 run>]
#<Thread:0x28f9920 dead>
#<Thread:0x28f9894 dead>
#<Thread:0x28f981c dead>

Mutexオブジェクトを作り、synchronizeメソッドを用いると、複数のインスタンスを確実に生成させようとするために、if 条件式の直後に「sleep 3」を入れていても、マルチスレッドでの単一インスタンス取得が実現できています。
RubyでSingletonパターン考察1 - Ruby入門勉強ルームの場合のMutexを使わないコードでは、Singletonパターンなのに、マルチスレッドでインスタンスが複数生成されていました。


Thread.listについて

Thread.listは、存在するスレッドのオブジェクトを配列で出力する。
スレッドオブジェクトは、run, sleep, deadなどの状態を保持しています。
ちなみに、Thread.listでは、メインスレッドもリストに現れるようです。
最初に4つ出力されたスレッドうち、runしているのがメインスレッド。
ほかのスレッドは、「sleep 3」により寝ている。

Thread#joinで、すべてのスレッド実行が終了するのを待った後、「Thread.list」を出力していますが、Thread.listでは、deadしたスレッドは出てこないようです。
deadしたスレッドは、「thread_list(threads)」という自作のメソッドにより、出力されている。


日時: 2009年08月19日 14:44
コメントを投稿






トラックバック

■この記事のトラックバックURL:
http://www.mapee.jp/mpe334/mt-tb.cgi/494

この記事にトラックバックされる方は、参照先が分かるようにするために、「RubyでSingletonパターン考察3・Mutexでマルチスレッド対応」へのリンクをお願いいたします。
以下のHTMLタグをトラックバック送信元ページ内に挿入して下さい。



※この記事へのリンクがない、また関連のないページからのトラックバックは反映されませんので、ご了承下さい。






あわせて読みたいブログパーツ
フィードメーター - Ruby勉強ルーム