4

次のようなクラスがあります。

public class Test {

private static final Object someObject = new Object();

public void doSomething()
{
    synchronized (someObject) {
        System.out.println(someObject.toString());
    }
}

}

オブジェクトが同期されていると見なすことができますか、それとも静的メンバーであるため問題がありますか?

編集:異なるスレッドが doSomething() にアクセスしている可能性があり、その場合、オブジェクトはスレッドセーフな方法でアクセスする必要があることに注意してください。

4

4 に答える 4

7

静的オブジェクトを監視オブジェクトとして使用することにより、Test クラスの任意のインスタンスを使用する 1 つのスレッドのみが同期ブロックに入ることができます。モニター オブジェクトが静的オブジェクトでない場合、Test クラスの異なるインスタンスを保持する他のスレッドが同期ブロックに入る可能性があります。

于 2008-11-24T16:16:07.913 に答える
4

ここで、 someObjectは、タイプ Test のすべてのオブジェクトのロック (モニター) として機能しています。つまり、doSomething() が Test の 2 つの別々のインスタンスで呼び出された場合、一方が完了する前に他方がブロックされます。これは、 someObjectをthisに置き換えた上記のコードとほぼ同等の同期メソッドとは異なります。

someObjectを非静的に変更すると、インスタンスごとのロックが発生します。これは基本的に、 Effective Javaの項目 70 で説明されている「プライベート ロック オブジェクト」のイディオムです。

于 2008-11-24T16:27:45.427 に答える
1

このようなクラス固有のインスタンスに依存しないロックを取得するための一般的なパターンは、Classオブジェクト自体を使用することです。

public class Test {
  public void doSomething() {
    synchronized (Test.class) {
      // something
    }
  }
}

これは事実上、同期された静的メソッドが行うことです。もちろん、このような複数のロックが必要な場合は、例のように静的フィールドとして宣言する必要があります。

于 2008-11-24T21:12:20.220 に答える
0

テストクラスが異なるクラスローダーを使用してロードされた場合はどうなりますか?

于 2010-12-14T16:15:02.177 に答える