問題タブ [double-checked-locking]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Javaで同期せずにスレッドセーフなシングルトン?
マルチスレッド アプリケーションとシングルトン クラスがあります。
もちろん、これは一般的なマルチスレッド シナリオでは機能しません。ただし、次のシナリオを検討してください。
- 最初はスレッドが1つしかありません
- この 1 つのスレッドが
getInstance()
初めて呼び出し、mc が初期化されます。 - その後、他のすべてのスレッドは最初のスレッドによって開始されます。
私の仮定:
フィールドの初期化とオブジェクトの構築は、他のスレッドを開始するmc
後続のすべての呼び出しの前に発生するため、これは機能するはずです。Thread.start()
そして、Thread.start()
スレッドの for は、そのスレッドの他のすべてのアクションの前に発生します。したがって、すべてのスレッドで正しい値が返されるmc
ように、他のすべてのスレッドですべてのアクションが先行発生します。getInstance()
この仮定は正しいですか?なぜ/なぜしないのですか?
java - ダブルチェックのロックは、怠惰な初期化シーンでのみ壊れていますか?
私はこの記事を読みました:「ダブルチェックロックが壊れています」宣言、それは言う
ダブルチェック ロックは、マルチスレッド環境で遅延初期化を実装するための効率的な方法として広く引用され、使用されています。
残念ながら、Java で実装した場合、プラットフォームに依存しない方法では確実に動作しません...
そして、この記事: Double-checked locking: Clever, but brokenには、次のように書かれています。
DCL イディオムは、遅延初期化をサポートするように設計されています...
私の質問は次のとおりです。
遅延初期化を実行しようとすると、二重チェックのロックが壊れるだけですか?
以下のコードのようなシーンでも壊れていますか(すべて初期化済みです)?
コード:
java - ConcurrentHashMap が Double Checked Locking で機能する理由
本「Java Concurrency in Practice」では、次のコードはスレッドセーフではないことが言及されています。
次の理由により、スレッドセーフではありません: - 1 つのスレッドがリソースの新しいインスタンスを作成できる - 「if」条件で同時に別のスレッドが空の参照を取得できないが、リソースのオブジェクトが完全に初期化されない
この質問には同様のコードがあります。リソースは concurentHashMap に格納され、人々はそれがスレッドセーフであると言います。このようなもの:
ConcurrentHashMap に値を格納するとコードが threadSafe になるのはなぜですか? ComplexObject が完全に初期化されず、この「部分オブジェクト」がマップに保存される可能性はまだあると思います。また、他のスレッドは、完全に初期化されていない部分的なオブジェクトを読み取ります。
「前に起こる」とは何かを知っていると思います。JDK 8.0_31 のコードを分析しましたが、まだ答えがわかりません。
computeIfAbsent、putIfAbsentなどの関数を認識しています。このコードは別の方法で記述できることを知っています。このコードをスレッドセーフにする詳細を知りたくないだけです。
java - シングルトンのインスタンス化を再確認する理由
このリンクでは、以下のようにシングルトンのインスタンス化を見つけました:
私は単一のチェック、つまり (1) のポイントを得ていません。ここで、単一のスレッドが同期ブロック内のインスタンスをチェックする方法は何ですか?最初のチェックを使用するポイントは何ですか?
java - volatile を使用しないダブルチェック ロック
二重チェックのロックを行う方法について、この質問を読みました。
私の目的は、フィールド (シングルトンではない) の遅延読み込みを volatile 属性なしで機能させることです。フィールド オブジェクトは、初期化後に変更されることはありません。
私の最終的なアプローチをいくつかテストした後:
再利用可能な Publisher クラスでシンプルさを保ちながら、揮発性を必要としないため、アクセス時間が短縮される可能性があります。
jcstressを使用してこれをテストしました。SafeDCLFinal は期待どおりに機能しましたが、UnsafeDCLFinal は一貫性がありませんでした (期待どおり)。この時点で 99% 確実に動作しますが、間違っていることを証明してください。でコンパイルしmvn clean install -pl tests-custom -am
て実行しjava -XX:-UseCompressedOops -jar tests-custom/target/jcstress.jar -t DCLFinal
ます。以下のテスト コード (主に変更されたシングルトン テスト クラス):
Java 8 でテスト済みですが、少なくとも Java 6 以降では動作するはずです。ドキュメントを見る
しかし、これが機能するかどうかは疑問です:
または多分:
または:
これは、このオラクルのドキュメントに基づいて機能すると思います:
final フィールドの使用モデルは単純です。オブジェクトのコンストラクタでオブジェクトの final フィールドを設定します。オブジェクトのコンストラクターが終了する前に、別のスレッドが参照できる場所に構築中のオブジェクトへの参照を書き込まないでください。これに従えば、オブジェクトが別のスレッドから見られるとき、そのスレッドは常に、そのオブジェクトの final フィールドの正しく構築されたバージョンを認識します。また、少なくとも最終フィールドと同じくらい最新の最終フィールドによって参照されるオブジェクトまたは配列のバージョンも表示されます。
c++ - この C++11 でのダブル チェック ロック パターン (DCLP) の実装は正しいですか?
DCLP (ダブルチェック ロック パターン) について読んでいますが、それが正しいかどうかわかりません。アトミックを使用してロックを作成する場合 ( C++11 で修正された DCLPで説明されているように)、不明な点が 2 つあります。
- 記事のコード:
"load()" 内でフェンスを取得した後、tmp が nullptr ではなく、単純に戻るとどうなりますか? CPU が「フェンスを解放」できる場所を述べるべきではありませんか?
また、フェンスを解放する必要がない場合、なぜ取得と解放を行う必要があるのでしょうか。違いはなんですか?
Surly 私は何か基本的なものを欠いています....
- 記事を正しく入手した場合、それは DCLP を実装する正しい方法でもありますか?
つまり、インスタンスを見る代わりに、アトミック ブール値を使用して DCLP が機能することを確認しています。それが正しいか?
ありがとう!
編集:シングルトンを実装するための質問をしているのではなく、単にフェンスとアトミックの概念とそれが DCLP をどのように修正したかをよりよく理解するために質問していることに注意してください。理論的な質問です。
java - Spring Bean の Db にアクセスする際のスレッド セーフ
スプリングレストコントローラーによって呼び出されているシングルトンスプリングサービスがあります。
シングルトン サービスには、次の実装を持つMyService
メソッドがあります。addRecordIfNotExistsBefore
問題は、明らかなように、2 つのクライアントが同時に同じサービスを要求すると、レコードがデータベースに 2 回追加されることです。
次のような簡単な実装で、ダブルチェックのイディオムを適用できます。
それは有効な解決策ですか、それとも別のより良い解決策がありますか?
c++ - volatile のみで DCLP を修正する
DCLP の問題を説明している記事「C++ とダブルチェック ロックの危険性」を読んでいます。
記事の第 2 部 (リンク先) では、C/C++ volatile だけで DCLP を試して解決する方法を示します (私の知る限り、これは不可能です)。記事では、ライターはその方法を説明していますが (最後の例は 11 番です)、次のように書いています。
残念ながら、これだけでは最初の問題に対処することはできません。C++ の抽象マシンはシングル スレッドであり、C++ コンパイラは、前述のようなソースからスレッドセーフでないコードを生成することを選択する可能性があります。そうしないと、最適化の機会が失われ、効率が大幅に低下します。このすべての後、振り出しに戻ります。しかし、待ってください。さらに多くのプロセッサがあります。
つまり、(私が正しく理解していれば) volatile をどれだけうまく使用しても機能しないということです」ちょうど言及した」
しかし、それは「C++ の抽象マシンはシングル スレッドである」とはどういう意味ですか?!
これらすべての揮発性物質を使用した上記の例では、並べ替えが妨げられないのはなぜですか?
ありがとう!