ダブルチェックロックです。当期純
-
23-08-2019 - |
質問
またこの 第 議論のダブルチェックロックパラダイムが壊れたJava.のパラダイムを有効とします。純(特にC#)場合、変数の宣言された volatile
?
解決
3番目のバージョンでは、この問題についてのC#の会談でSingletonパターンを実装します。
これは言います:
後者の場合にも、専門家の障壁が必要とされているかを正確に同意することはできませんが、明示的なメモリバリアは、呼び出してしまうと、揮発性のインスタンスが変数作ることは、それを動作させることができます。私は専門家がどのような権利だと何が悪いのは同意しない状況を回避しようとする傾向がある!
著者は、二重ロックが他の戦略よりも動作しにくくなるため、使用すべきではないことを示唆しているようだ。
他のヒント
今のロックをダブルチェックして、Javaで動作するだけでなく、C#(Javaのメモリモデルが変更され、これが効果の一つです)。しかし、あなたはそれがの正確の権利を取得する必要があります。少しでもあなた台無しにした場合、あなたも、スレッドの安全性を失うことに終わる可能性があります。
他の回答を述べてきたように、は、あなたがシングルトンパターンを実装している場合がありにそれを行うためのより良い方法があります。私はダブルチェックロッキングおよび「毎回ロック」のコードの間で選択する必要があり、状況にいる場合、私はそれがボトルネックの原因となったことを本当の証拠を得たと思いまで、個人的に、私はすべての時間をロックするために行くと思います。それがスレッドになると、シンプルで明らかに-正しいパターンは多くの価値があります。
Lazy<T>
パターンが間違って得ることについて何らかの懸念を奪う:.NET 4.0は、新しいタイプがあります。これは、新しいタスク並列ライブラリの一部です。
http://msdn.microsoft:MSDNは、コンピューティングデベロッパーセンターパラレル参照してください。 COM / EN-US /同時実行/ default.aspxをする
ところで、利用可能.NET 3.5 SP1のためにバックポート(私はそれがサポートされていないと信じて)<のhref = "http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx" のrel = "noreferrerがあります「>ここを。
Javaでより注(最も可能性の高い.NETでも)、シングルトン初期化するためのダブルチェックロックは完全に不要と同様に分解されます。彼らは最初に使用しているまでクラスが初期化されませんので、必要な遅延初期化は既にこのことによって実現される;
private static Singleton instance = new Singleton();
あなたのシングルトンクラスはシングルトンインスタンスが最初に使用される前にアクセスすることができる定数のようなものが含まれていない限りは、これはあなたがする必要があるすべてである。
私はすべての人がダブルチェックロックが悪いパターンであることを述べている理由を得ることはありませんが、それは正常に動作させるためにコードを適応していません。私の意見では、これ以下のコードはうまく動作するはずです。
このコードは、キャメロンの記事でmentionned問題に苦しむ場合は、誰かが私に言うことができれば行ってくださいます。
public sealed class Singleton {
static Singleton instance = null;
static readonly object padlock = new object();
Singleton() {
}
public static Singleton Instance {
get {
if (instance != null) {
return instance;
}
lock (padlock) {
if (instance != null) {
return instance;
}
tempInstance = new Singleton();
// initialize the object with data
instance = tempInstance;
}
return instance;
}
}
}
私が得ているダブルチェック(すなわち、怠惰な初期化を避けるために、プリミティブを使用して)ブール値を使用して動作するようにロッキングます:
ブールを使用したシングルトンは動作しません。あなたはメモリバリアを通過しない限り、異なるスレッド間で見られるように、動作の順序は保証されません。
換言すれば、第二のスレッドから分かるように、
created = true
がinstance= new Singleton();
前に実行することができる。
僕もそういっ実装パターンをダブルチェックロック(う業務をコンパイラの特殊性に様々な言語).Wikipediaの記事が話題のナイーブな手法としての問題解など簡単なこと(C#):
public class Foo
{
static Foo _singleton = null;
static object _singletonLock = new object();
public static Foo Singleton
{
get
{
if ( _singleton == null )
lock ( _singletonLock )
if ( _singleton == null )
{
Foo foo = new Foo();
// Do possibly lengthy initialization,
// but make sure the initialization
// chain doesn't invoke Foo.Singleton.
foo.Initialize();
// _singleton remains null until
// object construction is done.
_singleton = foo;
}
return _singleton;
}
}
Javaでは、ま利用同期()の代わりにロック()で基本的に同じアイデアです。場合が可能の不一致の場合、シングルトンの分野が割り当てられた、なぜならず利用の現地scoped変数を割り当てのシングルトンの分野での最後のタイミングで終了する前に、重要なのでしょうか。私何かが足りない?
あの引きるには以下のようにマイケル-borgwardtるクライアントまで、フルのC#、Java、staticフィールドが初期化されて再使用が その 行動の言語固有のものです。とに使用しましたこのパターンが頻繁に見を初期化のコレクションなどユーザーです。セッション).
私が得ているダブルチェック(すなわち、怠惰な初期化を避けるために、プリミティブを使用して)ブール値を使用して動作するようにロッキングます:
private static Singleton instance;
private static boolean created;
public static Singleton getInstance() {
if (!created) {
synchronized (Singleton.class) {
if (!created) {
instance = new Singleton();
created = true;
}
}
}
return instance;
}