9

クラスでフィールド注入を使用すると、次のようになります。

@Inject
private MyClass myField;

このフィールドの「安全な公開」ステータスについて何か推測できますか? 別の言い方をすれば、MyClass 自体がスレッドセーフであると仮定すると、このフィールドを使用する際に注意すべき同時実行のリスクはありますか?

私の本能は通常、可能であればすべてのフィールドを最終的に作成することですが、フィールド注入では機能しません。もちろん、コンストラクター インジェクションを使用することもできますが、通常は、プロキシ処理のためだけに追加の「偽の」引数なしコンストラクターを作成する必要があります。大した問題ではありませんが、フィールド注入を使用する方が便利です。別のオプションとして、フィールドを揮発性としてマークすることもできます (または、ロックを使用することもできます...) が、それは本当に必要ですか?

JSR-299 仕様は、この質問に答えていないようです。Weld などの実装で CDI を使用しています。

  • 注入先のオブジェクトは、複数のスレッドで使用されます (たとえば、@ApplicationScoped です) これ欲しい。
  • MyClass が不変の場合、安全な公開は問題にならないことを理解しています。しかし、必ずしも不変オブジェクトだけを注入するとは限りません。
  • MyClass 自体はスレッドセーフであると想定されています。これは私の関心事ではありません。Java メモリ モデルの規則により、スレッドが MyClass の半分構築されたインスタンスを参照する可能性など、厳密には安全でないパブリケーションに関する懸念があります。
4

4 に答える 4

2

Javaメモリモデルのセクション9.1.1に基づいてできると思います: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf 9.1.1 最終フィールドの構築後の変更 .. . final フィールドのフリーズは、finalフィールドが設定されているコンストラクターの最後と、リフレクションによる他の特別なメカニズムによる final フィールドの各変更の直後の両方で発生します。...

関連する Guice の議論は次のとおりです

.. およびhttp://www.theserverside.com/discussions/thread.tss?thread_id=52252#284713

ただし、DI フレームワークがこの明示的なステートメントを作成するとよいでしょう。

于 2013-07-03T04:30:12.597 に答える
1

注入されたインスタンスを使用する場合の同時実行のリスクは、そのインスタンスの有効範囲によって異なります。

MyClassがデフォルトのスコープ内にある場合@Dependent、各注入ポイントは独自のインスタンスを取得します。スレッド セーフに関する予防措置は、自分自身を呼び出した場合と同じですnew MyClass()。複数のスレッドからそのインスタンスにアクセスする場合は、それMyClassがスレッドセーフであることを確認するか、その周りに何らかの同期を提供する必要があります。

がまたはMyClassなどのより広い範囲にある場合、同じインスタンス (またはそのプロキシ) が同じコンテキスト内の複数の注入ポイントに注入される可能性があります。たとえば、アクセスする同じセッションからの並列ブラウザ リクエストがあり、注釈が付けられている場合、複数のスレッドが同じインスタンスに並列にアクセスする可能性があります。CDI はこれを同期するわけではないので、スレッドセーフであることを確認する必要があります。@SessionScoped@ApplicaionScopedMyClassMyClass@SessionScopedMyClass

于 2012-12-14T18:19:52.773 に答える
1

私は常にコンストラクターインジェクションを使用します。次に、フィールドが最終的なものになる可能性があり、スレッドの安全性について疑問の余地はありません。

于 2012-12-14T08:08:39.870 に答える