メソッドの前にsynchronize
キーワードを使うと、そのオブジェクトに同期がかかることは知っています。つまり、オブジェクトの同じインスタンスを実行している2つのスレッドが同期される。
しかし、同期はオブジェクト・レベルで行われるため、オブジェクトの異なるインスタンスを実行している2つのスレッドは同期されない。Javaクラスにメソッドによって呼び出される静的変数がある場合、そのクラスのインスタンス間で同期させたい。2つのインスタンスは2つの異なるスレッドで実行されている。
以下の方法で同期を実現できますか?
public class Test
{
private static int count = 0;
private static final Object lock= new Object();
public synchronized void foo()
{
synchronized(lock)
{
count++;
}
}
}
静的なオブジェクト lock
を定義し、そのロックにキーワード synchronized
を使用しているので、静的変数 count
はクラス Test
のインスタンス間で同期されているというのは本当でしょうか?
静的変数へのアクセスを同期させる方法はいくつかある。
1.同期スタティック・メソッドを使う。 これはクラス・オブジェクト上で同期をとります。
public class Test {
private static int count = 0;
public static synchronized void incrementCount() { 以下のようにします。
count++;
}
}
2.クラス・オブジェクトを明示的に同期させる。
public class Test {
private static int count = 0;
public void incrementCount() { 以下のようにします。
synchronized (Test.class) {
count++;
}
}
}
3.他の静的オブジェクトに同期する。
public class Test {
private static int count = 0;
private static final Object countLock = new Object();
public void incrementCount() { 以下のようにします。
同期 (countLock) { { count++; count++; count++
count++;
}
}
}
ロック・オブジェクトがクラスの外部に公開されないため、多くの場合、方法3が最適である。