クラス Employee があり、そのクラスのオブジェクトを次のように作成するとしましょう
Employee emp = new Employee();
以下の 2 つの同期ブロックの違いは何ですか
synchronized(emp){ } and
synchronized(Employee.class)
クラス Employee があり、そのクラスのオブジェクトを次のように作成するとしましょう
Employee emp = new Employee();
以下の 2 つの同期ブロックの違いは何ですか
synchronized(emp){ } and
synchronized(Employee.class)
最初のものは、1 つの Employee インスタンスをモニターとして使用します。2 つ目は、Employee クラスをモニターとして使用します。
目標が従業員のインスタンス変数を保護することである場合、最初のものは 2 番目のものよりもはるかに理にかなっています。目標が Employee クラスの静的変数を保護することである場合、2 番目のものは意味がありますが、最初のものは意味がありません。
最初のものは、クラスの特定のインスタンスで同期します。したがって、クラスの 2 つの異なるインスタンスで動作する 2 つのスレッドがある場合、それらは両方とも同時にブロックに入ることができます。もちろん、それぞれのコンテキスト内でです。
2 番目のブロックは、クラス自体で同期します。したがって、2 つの異なるインスタンスを持つ 2 つのスレッドがある場合でも、一度に 1 つのスレッドだけがブロックに入ります。
同期するときは、セマフォとして定義するオブジェクトが必要です。スレッド A がオブジェクト A によって定義された同期ブロック内にある場合、他のスレッドは、オブジェクト A によって定義された他のそのようなブロック内に存在することはできませんが、他のオブジェクトによって定義された他の同期ブロック内に存在することはできます。
emp
とEmployee.class
は別個のオブジェクトであるため、2 つの同期ブロックは互換性がありません (最初のブロック内にスレッドを、2 番目のブロック内に別のスレッドを持つことができます)。
より一般的な注意として、個々の従業員オブジェクトにのみ影響する機密コードを保護するために最初のブロックを使用し、1 人の従業員を変更すると他の従業員の重要なセクションまたはそれらのコレクション/集計値に影響を与える可能性がある操作で 2 番目のブロックを使用する必要があります。