2011-08-04 43 views
7

これは時期尚早の最適化、または時期尚早の警告であるかもしれませんが、いくつかのクラスでシングルトンを使用することは避けています。私はアプリをマルチスレッドとして実行する必要があることを心配しています。シングルトンは紛争と混乱を招くでしょう。シングルトンはRubyでこの問題を抱えているのですか?あるクラスがシングルトンを参照すると、同じスレッドのシングルトンだけが返されるような名前空間が構築されていますか?シングルトンクラスはマルチスレッドアプリケーションで問題を作成しますか?

編集:これらを明確にするために、これらのクラスを更新すると、それを見ている他のクラスが更新されるようになります。私はこれがスレッドセーフであるかどうかは分かりませんが、今私はこれらの観察可能なクラスを1トン前後で渡していることを知っています。それは厄介なものです。そして、彼らは自然なシングルトンクラスのように見えます。

+0

共有スコープ(シングルトンか)することができ、マルチスレッドアプリケーションで問題を引き起こします。 – R0MANARMY

+1

^それ!シングルトンのルビーミックスイン自体は、「あなたはすべてのスレッドで同じインスタンスを取得し、保証されます」という点でスレッドセーフです。マイケル・コールがすでに書いたように。しかし、 "あなたの"シングルトンの実装スレッドを安全に保つことはあなたの責任です。 – paukul

答えて

7

スレッドセーフであると書かれていないすべてのクラスは、シングルトンであるかどうかにかかわらず、マルチスレッド環境で問題を引き起こします。

クラスがシングルトンであるという事実は、デフォルトで共有されているため、問題を悪化させる可能性があります。スレッドごとにインスタンスを持つことはできません。

シングルトン状態が読み取り専用で不変の場合、スレッドの安全性の問題は発生しません。

共有状態が変更されている場合は、スレッドセーフであることを確認する必要があります。

+1

不変な私はこの場合十分ではない。これは、データへの読み取り専用アクセスを公開するが、その内部状態を変更するクラスである可能性があります。 – R0MANARMY

+0

+1の最初の行。 – AShelly

+1

内部状態を変更した場合、変更不可能ではありません。 – duffymo

2

これはYAGNIの場合のように思えるが、Singleton classthreadを必要とし、ドキュメントに次のように述べているん:

Klass._instantiate() - 返す ``インスタンス」」かnil?。このフック メソッドは、待機ループの にKlass.instance()を呼び出す2番目(またはn番目)のスレッドを挿入します。戻り値は、成功または最初の、またはより一般的には現在の の " "インスタンス化スレッドの早期終了を示します。

これは役に立ちますか?

6

ここでは、シングルトンスレッドセーフを行う例を示します。状態(@things)を持ち、不変(読み取り専用)でない他のオブジェクトと同様に扱わなければなりません。 getterとsetterはMutex(相互排除)を介して内部状態にアクセスする必要があります。

require 'singleton' 

class MyObject 
    include Singleton 

    def initialize 
    @things = [] 
    @mutex = Mutex.new 
    end 

    def add(thing) 
    with_mutex { @things << thing } 
    end 

    def things 
    with_mutex { @things } 
    end 

    def clear 
    with_mutex { @things.clear } 
    end 

    def self.add(thing) 
    instance.add(thing) 
    end 

    def self.things 
    instance.things 
    end 

    def self.clear 
    instance.clear 
    end 

    private 

    def with_mutex 
    @mutex.synchronize { yield } 
    end 
end 

さらにリーディング:http://rubylearning.com/satishtalim/ruby_threads.html

+1

メソッドでMutex.newを呼び出すと、2つのスレッドが同時に@mutex変数を上書きして初期化を開始できる状態になることが考えられます。 – Zmey

+0

@Zmeyありがとうございます - 私はこれを反映するコードを修正:) – Kris

関連する問題