1

次のようにオブジェクトを想定します。

My Object { 
private String field1 = "";
private  String field2 = "";

/*getters and setters for field1 and field2 */

boolean isField1inDocument (String document) {
      if (document.indexOf(field1) > -1) return true;
      else return false;
 }

}

メソッドisField1inDcoumentスレッドは安全ですか?あるスレッドから返されたブール値が、メソッドを同時に実行している別のスレッドによって作成されたブール値と何らかの形で衝突する可能性があるのではないかと心配しています。メソッドにフィードされるドキュメントは個々のスレッドからのものであり、ドキュメント自体は衝突できません。私はこのメソッドを同期できることを知っています。私はこれが必要かどうかを理解しようとしています。

4

3 に答える 3

2

論理的には、 isField1inDocument() の動作はドキュメント (スレッドのみが所有していると言う) と field1 の値のみに依存します。フィールド 1 のセッターがあるため、現在のスレッドが isField1inDocument() 計算を実行している間に別のスレッドによってフィールド 1 が変更されるシナリオを想像することができるため、スレッドセーフではありません。

これは、field1 の値を渡すことで修正できます。

boolean isField1inDocument (String document, String field1){...

または、呼び出し元スレッドから、囲んでいる MyObject のプライベート インスタンスを保持することによって

new MyObject().isField1InDocument(document)
于 2012-05-02T03:26:12.453 に答える
1

いいえ、これはスレッドセーフではありません。

その理由は、インスタンス変数である field1 にアクセスしているためです。他のスレッドが、メソッド内でアクセスされている間に field1 を変更する可能性があり、その結果、計算が正しくなくなります。

この問題を修正するには、複数の方法があります。

  • パラメータの一部として field1 を渡します

    boolean isField1inDocument (文字列ドキュメント、文字列フィールド 1)

この場合、メソッドはスタック上に存在し、スレッドごとに別のスタックが存在するため、スレッド インターリーブの問題はありません。

  • 1 つのスレッドのみが field1 にアクセスできるようにコードを同期して、 と のセッター メソッドをfield1同じisField1inDocumentオブジェクトで同期する必要があります。同期を行うとスループットが低下するので注意が必要です。
  • field1 を final にできる場合、この場合は初期化できず、スレッドの安全性に関する懸念は解消されます。
于 2012-05-02T03:25:56.620 に答える
0

フィールドを final として宣言すると、このメソッドはスレッド セーフになり、フィールド 1 が変更される可能性はなくなります。

于 2012-05-02T03:28:49.463 に答える