synchronized キーワードには 2 つの用途があります。 1 つ目は、記事「クラス メソッドを同期するための Synchronized キーワードの使用」で紹介されているように、メソッドの定義で直接使用する方法です。もう 1 つのタイプは同期ブロックです。同期ブロックを通じてオブジェクト変数を同期できるだけではありません。同期ブロックを使用して、クラス内の静的メソッドと非静的メソッドを同期することもできます。
同期ブロックの構文は次のとおりです。
次のようにコードをコピーします。
パブリック void メソッド()
{
… …
同期化された(式)
{
… …
}
}
1. 非静的クラスメソッドの同期
「クラス メソッドを同期するための Synchronized キーワードの使用」の記事から、synchronized キーワードを使用してメソッドを定義すると、クラス内の synchronized キーワードを使用して定義されたすべての静的メソッドまたは非静的メソッドがロックされることがわかりますが、これを理解するのは簡単ではありません。同期ブロックを使用して同じ効果を実現する場合、なぜこの効果が発生するかを理解するのは難しくありません。同期ブロックを使用してクラス内のすべての同期非静的メソッドをロックする場合は、これを同期ブロックのパラメーターとして使用し、同期ブロックの国に渡す必要があります。コードは次のとおりです。
同期ブロックを介して非静的メソッドを同期する
次のようにコードをコピーします。
パブリッククラスSyncBlock
{
パブリック void メソッド1()
{
synchronized(this) // Method1 メソッドで synchronized キーワードを使用するのと同等
{
… …
}
}
パブリック void メソッド2()
{
synchronized(this) // Method2 メソッドの synchronized キーワードの使用と同等
{
… …
}
}
パブリック同期ボイドメソッド3()
{
… …
}
}
上記のコードでは、同期ブロックがメソッド 1 とメソッド 2 で使用されています。 017 行目のメソッド 3 メソッドでは、引き続き synchronized キーワードを使用してメソッドを定義しています。同じ SyncBlock クラスのインスタンスを使用する場合、3 つのメソッドのうち 1 つが実行されている限り、同期ロックが取得されないため、他の 2 つのメソッドはブロックされます。 synchronized ブロックを使用するときに synchronized キーワードと同じ効果を実現するには、すべてのコードを synchronized ブロックに記述する必要があります。そうしないと、現在のメソッドのすべてのコードが他のメソッドと同期されなくなります。
これを同期ブロックのパラメーターとして使用することに加えて、SyncBlock.this を同期ブロックのパラメーターとして使用して、同じ効果を実現することもできます。
内部クラス (InnerClass) のメソッドで synchronized ブロックを使用する場合、これは内部クラスのみを表し、外部クラス (OuterClass) とは関係ありません。ただし、内部クラスの非静的メソッドは、外部クラスの非静的メソッドと同期できます。たとえば、method4 メソッドを内部クラス InnerClass に追加し、method4 メソッドを SyncBlock の 3 つのメソッドと同期します。コードは次のとおりです。
内部クラスの非静的メソッドと外部クラスの非静的メソッドを同期する
次のようにコードをコピーします。
パブリッククラスSyncBlock
{
… …
クラス内部クラス
{
パブリック void メソッド4()
{
同期済み(SyncBlock.this)
{
… …
}
}
}
… …
}
上記の SyncBlock クラスの新しいバージョンでは、InnerClass クラスのメソッド 4 メソッドが SyncBlock クラスの他の 3 つのメソッドと同期されるため、メソッド 1、メソッド 2、メソッド 3、およびメソッド 4 の 4 つのメソッドのうち 1 つのメソッドのみを実行できます。同じ時間です。
同期ブロックが正常に実行された場合でも、プログラムエラーにより同期ブロックから異常終了した場合でも、現在の同期ブロックが保持していた同期ロックは自動的に解除されます。したがって、同期ブロックを使用するときに同期ロックの解放について心配する必要はありません。
2. 静的クラスメソッドの同期
静的メソッドを呼び出すときに、オブジェクト インスタンスが必ずしも作成されるわけではないためです。したがって、これを使用して静的メソッドを同期することはできませんが、静的メソッドを同期するには Class オブジェクトを使用する必要があります。コードは次のとおりです。
同期ブロックを介して静的メソッドを同期する
次のようにコードをコピーします。
パブリック クラス StaticSyncBlock
{
パブリック静的無効メソッド1()
{
同期化(StaticSyncBlock.class)
{
… …
}
}
public static synchronized void method2()
{
… …
}
}
静的メソッドを同期する場合、クラスの静的フィールド クラスを使用して Class オブジェクトを取得できます。上記の例では、method1とmethod2のどちらか一方のメソッドのみを同時に実行できます。 class フィールドを使用して Class オブジェクトを取得するだけでなく、インスタンスの getClass メソッドを使用して Class オブジェクトを取得することもできます。上記の例のコードは次のように変更できます。
getClassメソッドを使用してClassオブジェクトを取得します。
次のようにコードをコピーします。
パブリック クラス StaticSyncBlock
{
パブリック静的 StaticSyncBlock インスタンス。
public StaticSyncBlock()
{
インスタンス = これ;
}
パブリック静的無効メソッド1()
{
同期化(instance.getClass())
{
}
}
}
上記のコードでは、StaticSyncBlock クラスのインスタンスはパブリック静的インスタンスを通じて取得され、Class オブジェクトはこのインスタンスの getClass メソッドを通じて取得されます (クラスのすべてのインスタンスは getClass メソッドを通じて同じ Class オブジェクトを取得します。したがって、任意の呼び出し (インスタンスの getClass メソッドを使用できます)。 Test クラスの静的メソッド メソッドや StaticSyncBlock クラスの 2 つの静的メソッドなど、Class オブジェクトを通じてさまざまなクラスの静的メソッドを同期することもできます。コードは次のとおりです。
Test クラスのメソッドメソッドは、StaticSyncBlock クラスのメソッド 1 およびメソッド 2 と同期されます。
次のようにコードをコピーします。
パブリッククラステスト
{
パブリック静的 void メソッド()
{
同期化(StaticSyncBlock.class)
{
}
}
}
注: 同期ブロック同期クラス メソッドを使用する場合、非静的メソッドはこれを使用して同期できますが、静的メソッドは同期に Class オブジェクトを使用する必要があります。それらは互いに影響しません。もちろん、非静的メソッドで Class オブジェクトを使用して静的メソッドを同期することもできます。ただし、これを静的メソッドで使用して非静的メソッドを同期することはできません。これは、同期ブロック同期クラス メソッドを使用する場合に注意する必要があります。