異なる場所で使用した場合のコードへの synchronized の影響:
1. synchronized キーワード変更メソッド
このクラスは、次の状況で同期ブロックまたは同期メソッドを定義すると仮定します。 P2 はそれらを呼び出すことができます。
public synchronized void method(){
//
}
これが同期メソッドであり、このとき同期ロックするのはこの同期メソッドオブジェクトの呼び出しです。言い換えると、オブジェクト P1 が異なるスレッドでこの同期メソッドを実行すると、それらの間で相互排他が形成され、同期効果が得られます。同時に、オブジェクト内に複数の同期メソッドがある場合、スレッドがオブジェクト内の同期メソッドを実行すると、オブジェクト内の他の同期メソッドは他のスレッドによって実行できなくなります。ただし、このオブジェクトが属するクラスが生成する別のオブジェクトP2は、synchronizedキーワードを付加してこのメソッドを任意に呼び出すことができる。
上記のコード例は、次のコードと同等です。
public void method() {
synchronized (this)
{
P1 のスレッドのみが P1 の同期メソッドを呼び出すことができます。 P2 の場合、P1 のロックには何もありません。この場合、プログラムが同期メカニズムの制御を逃れて、データの混乱を引き起こす可能性もあります。
2. Synchronizedブロックのサンプルコードは以下の通りです:
public void method(SomeObject so) {
synchronized(so)
{ //..
}
}
このとき、ロックはsoオブジェクトであり、各オブジェクトが対応していますしたがって、オブジェクト ロックを取得したスレッドは、そのスレッドが制御するコードを実行できます。ロックとしてクリアなオブジェクトがある場合は、このようにプログラムを書くことができますが、ロックとしてクリアなオブジェクトがなく、コードの一部を同期したいだけの場合は、特別なインスタンス変数を作成できます (それは必ずオブジェクト) をロックとして機能させます:
private byte[] lock = new byte[0];
Public void method(){
synchronized(lock) }
}
3. synchronized を静的関数に適用するサンプル コードは次のとおりです。
Class Foo
{ public synchronized static void method1()
{ //. public void method2()
{
synchronized(Foo.class) /
これら 2 つの同期メソッドはどちらも、このメソッドのオブジェクトが属するクラス (このクラスによって生成された特定のオブジェクトではなく、クラス) のクラス ロックを呼び出します。
これは推測できます: 同期静的関数 A がクラスで定義されており、同期インスタンス関数 B も定義されている場合、このクラスの同じオブジェクト Obj が複数のスレッドでそれぞれ A メソッドと B メソッドにアクセスすると、ロックがすべて異なるため、同期は行われません。メソッド A のロックは Obj が属するクラスであり、メソッド B のロックは Obj が属するオブジェクトです。