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

スポンサーリンク
スポンサーリンク
ライフスタイル関連のコンテンツ
お金 | 仕事 | 勉強 | プライベート | 健康 |
プログラミング関連のコンテンツ
C言語/C++入門 | Ruby入門 | Python入門 | プログラミング全般

前回、RubyでSingletonパターン考察1で、if 条件判定によるSingletonパターンを書いてみましたが、これはマルチスレッドの場合に複数インスタンスが生成されてしまう問題がありました。

スポンサーリンク

Singletonパターンをマルチスレッド対応

RubyでSingletonパターンを、マルチスレッドにも対応させてみます。
Javaの書き方の定石である、スタティック変数(Rubyでいうクラス変数)にSingletonとなるインスタンス変数を保持します。
newメソッドをprivateにして、外部から直接newさせないようにするのは、前回と同じです。

class Singleton2
  @@singleton = new
 
  # new をprivateにする
  private_class_method(:new)
 
  def self.singleton
    return @@singleton
  end
end
 
puts "--- マルチスレッドの場合 ---"
threads = []
for i in 1..3
  t = Thread.new do
    obj =  Singleton2.singleton
    puts "#{obj.object_id}\n"
  end
  threads << t
end
threads.each do |th|
  th.join
end

実行結果。

--- マルチスレッドの場合 ---
21102470
21102470
21102470

今度の場合、別のスレッドに切り替わることで、複数インスタンスが生成されるような問題箇所はありません。
こっちのほうが、書くのも簡単だと思います。

PHPの場合

実は、Rubyで書く前に、PHPで実験していたのですが、PHPの場合、同じような以下のコードが動きません。(バージョン PHP5.2.5)

<?php
class Singleton {
    private static $singleton = new Singleton();
    private function __construct() {
    }
    public static function getInstance() {
        return self::$singleton;
    }
}
$single = Singleton::getInstance();
var_dump($single);
?>

http://codepad.org/2luFyufKでの実行結果。

Parse error: syntax error, unexpected T_NEW on line 3

「private static $singleton = new Singleton();」の行を、「private static $singleton = "hoge";」とただの文字列にしてやると・・・

string(4) "hoge"

と実行結果が返ってきたことから、PHPの場合、クラス内のstatic変数への代入は文字列ならOKらしいが、クラス内のstatic変数(Rubyでいうクラス変数)では、newできないのでしょうか?
ということで、PHPでのマルチスレッド対応なSingletonパターンは、どうやって作成するのか分からないままです。

スポンサーリンク
 
スポンサーリンク