1

非プリミティブ変数 ( myObject) のロックをテストするために作成したクラスに従うことを検討してください。すべてのスレッドが の同じオブジェクト インスタンスで動作している場合SynchronizationTest、私の質問は次のとおりです。

set(...)スレッド1がメソッドを実行している場合、他のスレッド(スレッド2としましょう)はまたはのいずれかを実行しても問題ないanotherSetWithSynchronized(...)ことを理解していますanotherSetWithoutSynchronized(...)

  1. thread1 がSynchronizationTest実行中のオブジェクトをロックした場合set(...)、それはすべてのメンバー オブジェクト変数のロックを取得したことを意味しますか? この場合のようにmyObject。そうでない場合は、

  2. スレッド 1 が実行されている場合、スレッド 2 は同時に実行set(...)できanotherSetWithSynchronized(...)ますか?

  3. スレッドで同時に実行できる 2 つのメソッドはありませんか?

  4. この設計は間違っていますか?メソッドを明示的にロックする必要がありますmyObjectsynchronized set(...)。このような:

    public synchronized void set(MyValue myValue) {
        synchronized (myObject) {
            myObject.put(myValue);
        }
    } 
    

これが私のコードです:

public class SynchronizationTest {
  private MyObject myObject = new MyObject();

  public synchronized void set(MyValue myValue) {
    myObject.put(myValue);
  }

  public void anotherSetWithSynchronized(MyValue myValue) {
    synchronized (myObject) {
      myObject.put(myValue);
    }
  }

  public void anotherSetWithoutSynchronized(MyValue myValue) {
    myObject.put(myValue);
  }
}
4

3 に答える 3

6

1: いいえ、set(...) メソッドは「SynchronizationTest」オブジェクトのロックによって保護されています。

2: はい、あなたが設計したように、それらのガード オブジェクトは異なります。

3: 1 つのスレッドは、一度に 1 つのメソッドしか実行できません。説明したように、2 つのスレッドを意味する場合、メソッドは 2 つのオブジェクトによって保護されているため、同時に実行できます。

4: はい、その通りです。


Java の固有ロックは、『Java Concurrency In Practice』という本で次のように説明されています。

同期ブロックには、ロックとして機能するオブジェクトへの参照と、そのロックによって保護されるコードのブロックの 2 つの部分があります。同期メソッドは、メソッド本体全体にまたがる同期ブロックの省略形であり、そのロックはメソッドが呼び出されているオブジェクトです。(静的同期メソッドは、ロックに Class オブジェクトを使用します。)


詳細については、「Java concurrency in Practice」のセクション 2.3.1 を参照してください。

于 2012-05-21T07:30:27.230 に答える
0

オブジェクトのスレッドロックはメンバーオブジェクトのロックも保証しますか?

いいえ。

thread1 が set(...) メソッドを実行している場合、他のスレッド (thread2 としましょう) は anotherSetWithSynchronized のいずれかを実行しても問題ないことを理解しています

はい、myObject が「this」と同じ値でない限り。

于 2012-05-21T07:14:38.223 に答える
0

同期メソッドは次と同等です

public void method(){
   synchronized(this){
      //something
   } 
}

1) いいえ

同期は、そのメンバーではなく、指定されたオブジェクトに対してのみ行われます。

2) いいえ

3)はい、できません。特定のモニターによって保護された同期セクション内でアクティブにできるスレッドは1つだけです

4)必要はありません(明示的な同期を使用している場合は、メソッドレベルで同期を使用しないでください)。ただし、同期が発生するインスタンスにアクセスできるユーザーを制御できるため、(ライブラリ/大規模なコードベースの場合) より優れているため、他の誰かが同期してデッドロックを引き起こすことができません。

于 2012-05-21T07:19:31.417 に答える