問題タブ [thread-safety]
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.
c# - インスタンスコンストラクターは静的メンバーを設定しますが、スレッドセーフですか?
私はいくつかのコードをリファクタリングしていlock
て、インスタンスコンストラクターでの使用について疑問に思っています。
確認してください
- インスタンスコンストラクタはスレッドセーフです。
- lockステートメントは、静的な「counter」メンバーではなく、そのコードブロックへのアクセスを防ぎます。
元のプログラマーの意図が各インスタンスにその「カウント」を認識させることであった場合、「カウンター」メンバーへのアクセスを同期して、別のスレッドが新しいスレッドではないことを確認し、MyClass
このスレッドがカウント?
参考までに-このクラスはシングルトンではありません。インスタンスは、単にその数を認識している必要があります。
c# - シングルトンのメンバーのスレッドセーフな使用
複数のクラスが使用する C# シングルトン クラスがあります。Instance
メソッドへのアクセスはToggle()
スレッドセーフですか? はいの場合、どのような仮定、ルールなどによって。いいえの場合、なぜ、どのように修正できますか?
java - DocumentBuilder.parse() はスレッドセーフですか?
標準の Java 1.6 javax.xml.parsers.DocumentBuilderクラスはスレッドセーフですか? 複数のスレッドから並行して parse() メソッドを呼び出すことは安全ですか?
JavaDoc はこの問題について言及していませんが、 Java 1.4の同じクラスの JavaDoc は、同時実行を意図していないと具体的に述べています。1.6ではそうだと思いますか?
その理由は、ExecutorService で数百万のタスクを実行しており、毎回 DocumentBuilderFactory.newDocumentBuilder() を呼び出すのはコストがかかるように思われるからです。
java - Java での String オブジェクトの同期
特に、数百人のユーザーが同じページにアクセスし、このページで約 10 秒ごとに更新を行うことが予想される機能について、いくつかの負荷/パフォーマンス テストを行っている Web アプリケーションがあります。この関数を使用して改善できることがわかった領域の 1 つは、データが変更されないため、Web サービスからの応答を一定期間キャッシュすることでした。
この基本的なキャッシングを実装した後、さらにいくつかのテストを行ったところ、並行スレッドが同時にキャッシュにアクセスする方法を考慮していないことがわかりました。約 100 ミリ秒以内に、約 50 のスレッドがキャッシュからオブジェクトをフェッチしようとしていて、有効期限が切れていることを発見し、Web サービスにアクセスしてデータをフェッチし、オブジェクトをキャッシュに戻していることがわかりました。
元のコードは次のようになります。
したがって、オブジェクトの有効期限が切れたときに 1 つのスレッドだけが Web サービスを呼び出していることを確認するにはkey
、キャッシュの get/set 操作を同期する必要があると考えました。同期します (この方法では、電子メール b@b.com に対するこのメソッドへの呼び出しは、a@a.com へのメソッド呼び出しによってブロックされません)。
メソッドを次のように更新しました。
また、「同期ブロックの前」、「同期ブロックの内側」、「同期ブロックを離れようとしています」、「同期ブロックの後」などのログ行を追加したので、get/set 操作を効果的に同期しているかどうかを判断できました。
ただし、これが機能しているようには見えません。テスト ログには次のような出力があります。
get/set 操作の前後で同期ブロックに出入りするスレッドを一度に 1 つだけ見たかったのです。
String オブジェクトの同期に問題はありますか? キャッシュキーは操作に固有であるため、良い選択だとfinal String key
思いました。メソッド内で宣言されていても、各スレッドが同じオブジェクトへの参照を取得するため、これで同期されると考えていました単一のオブジェクト。
ここで何が間違っていますか?
更新: ログをさらに調べたところ、次のように、キーが常に同じである同じ同期ロジックを持つメソッドのようです。
同じ並行性の問題は発生しません。一度に 1 つのスレッドだけがブロックに入ります。
更新 2 : 助けてくれてありがとう! ing Stringsに関する最初の回答を受け入れましたintern()
。これにより、最初の問題が解決されました。複数のスレッドが同期ブロックに入るべきではないと思っていた場所に、key
の値が同じであるためです。
他の人が指摘しているintern()
ように、そのような目的で使用し、それらの文字列を同期することは、実際には悪い考えであることが判明しました.webappに対してJMeterテストを実行して予想される負荷をシミュレートすると、使用されるヒープサイズが20分弱。
現在、メソッド全体を同期するだけの単純なソリューションを使用していますが、martinprobst と MBCook が提供するコード サンプルが非常に気に入っていますが、現在、このクラスには約 7 つの同様のメソッドgetData()
があるため (約 7 つの異なるデータが必要なため)ロックの取得と解放に関するほとんど重複したロジックを各メソッドに追加したくありませんでした。しかし、これは間違いなく、将来の使用にとって非常に価値のある情報です。これらは、このようなスレッドセーフな操作を行うための最善の方法に関する最終的な正解だと思います。できれば、これらの回答にもっと投票したいと思います!
.net - スレッドセーフなBindingListを書いた人はいますか?
現在、複数のスレッドで IBindingList を変更すると例外が発生します。自分で作成する前に、スレッドセーフなバージョンを持っている人はいますか?
c# - スレッドセーフなディクショナリを実装する最良の方法は何ですか?
IDictionary から派生させ、プライベート SyncRoot オブジェクトを定義することで、C# でスレッド セーフな Dictionary を実装することができました。
次に、コンシューマ全体 (複数のスレッド) でこの SyncRoot オブジェクトをロックします。
例:
私はそれを機能させることができましたが、これは醜いコードになりました。私の質問は、スレッドセーフな辞書を実装するためのより優れた、よりエレガントな方法はありますか?
c# - クラス設計: スレッドセーフとテスト容易性を考慮して、データファイルをクラスにまとめる
C# (.net 3.5) でアプリを作成していますが、クラスの設計について質問があります。
ファイルにアクセス (読み取り、書き込み) し、そのコンテンツをクラスのユーザー (インスタンス作成者) に提供するクラスを作成したいと考えています。インスタンスに対する最も一般的な操作は、ファイルから特定の値を取得することです。実際の読み取りおよび書き込み (io) 操作は非常にコストがかかるため、ファイル データをメモリに保持し、すべてのインスタンスがこのデータにアクセスできるようにしたいと考えています。このクラスは、さまざまなアプリケーションから同時に使用されるアセンブリに配置されているため、スレッド セーフについて心配する必要があると思います。
スレッドセーフと単体テスト容易性に関してこれを設計するにはどうすればよいですか (単体テストの場合、運用コードとは異なる入力ファイルを使用する必要があります)。どんな助けでも大歓迎です。
java - Javaコードを常にスレッドセーフにするべきですか、それともパフォーマンス上の理由から必要な場合にのみ行うべきですか?
現時点では単一のスレッドでのみ使用されるクラスを作成する場合、現時点では必要がなくても、それらをスレッドセーフにする必要がありますか? 後でこのクラスを複数のスレッドで使用する可能性があり、その時点で競合状態が発生する可能性があり、最初にクラスをスレッドセーフにしなかった場合、競合状態を見つけるのに苦労する可能性があります。または、パフォーマンスを向上させるために、クラスをスレッドセーフではないものにする必要がありますか? しかし、時期尚早の最適化は悪です。
別の質問: 必要に応じてクラスをスレッドセーフにする必要がありますか (複数のスレッドで使用する場合、そうでない場合)、必要に応じてこの問題を最適化する必要がありますか (同期が処理時間の重要な部分を消費することがわかっている場合)?
両方の方法のいずれかを選択した場合、デメリットを軽減する方法はありますか? または、使用する必要がある 3 番目の可能性はありますか?
編集:この質問が頭に浮かんだ理由を述べます。当社では、データをプロパティ ファイルに書き込む非常に単純なユーザー管理を作成しました。私はそれをWebアプリで使用しましたが、いくつかの作業を行った後、ユーザー管理がユーザーのプロパティ(名前とパスワードを含む)とロールを忘れたという奇妙なエラーが発生しました。それは非常に厄介でしたが、一貫して再現可能ではなかったので、競合状態だったと思います. ディスクからの読み取りとディスクへの書き込みのすべてのメソッドを同期したので、問題はなくなりました。そもそも同期を使ってクラスを書いていれば、おそらくすべての面倒を避けることができたのではないかと思いましたか?
EDIT 2 : Pragmatic Programmer のヒントを見ていると、ヒント #41: Always Design for Concurrency を見ました。これは、すべてのコードがスレッド セーフであるべきだと言っているわけではありませんが、並行性を念頭に置いて設計する必要があることを示しています。
c++ - この C++ 実装は Atomic float に対して安全ですか?
編集:ここのコードにはまだいくつかのバグがあり、パフォーマンス部門では改善される可能性がありますが、これを修正しようとする代わりに、記録として、インテルのディスカッション グループに問題を持ち込んで、多くの素晴らしいフィードバックを得ました。すべてがうまくいけば、Atomic float の洗練されたバージョンが Intel の Threading Building Blocks の近い将来のリリースに含まれる予定です。
これは難しい問題です。超高速のグラフィックス パフォーマンスのためではなく、クラスのデータ メンバーとして日常的に使用するために、Atomic float が必要です。また、これらのクラスでロックを使用することによる代償を払いたくありません。それは、私のニーズに対して追加の利点を提供しないからです。
intel の tbb と私が見た他のアトミック ライブラリでは、整数型はサポートされていますが、浮動小数点はサポートされていません。それで私は続けて実装しましたが、うまくいきました...しかし、それが本当にうまくいくかどうかはわかりません。
これがある種のスレッド異端ではないかどうか、ここにいる人は誰でも知っていますか?
ありがとう!
編集: Greg Rogers が提案したように size_t を uint32_t に変更しました。
編集:いくつかの修正を加えて、全体のリストを追加しました。
その他の編集:私のマシンで 100 スレッドで 5.000.000 += 操作にロックされたフロートを使用すると、3.6 秒かかりますが、愚かな do-while を使用しても、同じ作業を行うには 0.2 秒かかります。したがって、30 倍を超えるパフォーマンスの向上は、その価値があることを意味します (これが問題です)。
さらに編集: Awgn が指摘したように、私のfetch_and_xxxx
パーツはすべて間違っていました。それを修正し、よくわからない API の部分を削除しました (テンプレート化されたメモリ モデル)。コードの繰り返しを避けるために、演算子 += に関して他の操作を実装しました
追加:演算子 *= と演算子 /= が追加されました。フロートはそれらがなければフロートにならないためです。これに気付いたというピーターチェンのコメントのおかげで
編集:コードの最新バージョンは次のとおりです(参照用に古いバージョンを残します)
c++ - MatlabエンジンAPIのスレッドセーフ
試行錯誤の結果、MATLABエンジン関数は完全にスレッドセーフではないことがわかりました。
誰かがルールを知っていますか?
試行錯誤で発見:
Windowsでは、MATLABへの接続はCOMを介して行われるため、COMApartmentのスレッドルールが適用されます。すべての呼び出しは同じスレッドで発生する必要がありますが、各接続が分離されている限り、複数の接続が複数のスレッドで発生する可能性があります。
以下の回答から、これはUNIXには当てはまらないようです。UNIXでは、呼び出しが連続して行われる限り、複数のスレッドから呼び出しを行うことができます。