Javaのドキュメントには次のように書かれています:
同じオブジェクトに対する同期メソッドの 2 つの呼び出しをインターリーブすることはできません。
これは静的メソッドにとって何を意味するのでしょうか? 静的メソッドには関連付けられたオブジェクトがないため、synchronized キーワードはオブジェクトではなくクラスをロックしますか?
Javaのドキュメントには次のように書かれています:
同じオブジェクトに対する同期メソッドの 2 つの呼び出しをインターリーブすることはできません。
これは静的メソッドにとって何を意味するのでしょうか? 静的メソッドには関連付けられたオブジェクトがないため、synchronized キーワードはオブジェクトではなくクラスをロックしますか?
Oscar の (簡潔で嬉しい!) 回答に少し詳細を追加すると、Java 言語仕様の関連セクションは8.4.3.6、「同期メソッド」です。
同期メソッドは、実行前にモニター ( §17.1 ) を取得します。クラス (静的) メソッドの場合、メソッドのクラスの Class オブジェクトに関連付けられたモニターが使用されます。インスタンス メソッドの場合、これ (メソッドが呼び出されたオブジェクト) に関連付けられたモニターが使用されます。
注意しなければならない点の 1 つは (通常、数人のプログラマーがその罠に陥ります)、同期された静的メソッドと同期された非静的メソッドの間にリンクがないことです。つまり、次のようになります。
class A {
static synchronized f() {...}
synchronized g() {...}
}
主要:
A a = new A();
スレッド 1:
A.f();
スレッド 2:
a.g();
f() と g() は互いに同期されていないため、完全に同時に実行できます。
次のようにg()を実装しない限り:
g() {
synchronized(getClass()) {
...
}
}
このパターンは、オブジェクトの異なるインスタンス間で相互排除を実装する場合にも役立ちます(たとえば、外部リソースにアクセスするときに必要になります)。
Intrinsic Locks and Synchronizationに関する Oracle のドキュメント ページを参照してください。
静的メソッドはオブジェクトではなくクラスに関連付けられているため、静的同期メソッドが呼び出されるとどうなるか疑問に思うかもしれません。この場合、スレッドは class に関連付けられた Class オブジェクトの固有ロックを取得します。したがって、クラスの静的フィールドへのアクセスは、クラスのインスタンスのロックとは異なるロックによって制御されます。
静的メソッドには、関連付けられたオブジェクトもあります。JDK ツールキットの Class.class ファイルに属します。.class ファイルが RAM にロードされると、Class.class はテンプレート オブジェクトと呼ばれるそのインスタンスを作成します。
例:-既存の顧客クラスからオブジェクトを作成しようとすると
Customer c = new Customer();
Customer.class が RAM にロードされます。その瞬間、JDK ツールキットの Class.class は Template オブジェクトと呼ばれるオブジェクトを作成し、その Customer.class をそのテンプレート オブジェクトにロードします。その Customer.class の静的メンバーは、そのテンプレート オブジェクトの属性とメソッドになります。
したがって、静的メソッドまたは属性にもオブジェクトがあります