オブジェクトレベルのロックとクラスレベルのロックとはどういう意味ですか?
staticメソッドをロックすると、オブジェクト自体がロックされ、ごとClassにこれらの1つがありますClassLoader。あなたの例では、
public static synchronized int getCount(){
これはオブジェクトをロックしておりCounter.class、次と同じです。
public static int getCount() {
synchronized (Counter.class) {
}
代わりに、そうでない staticメソッドをロックしている場合は、そのメソッドを所有しているオブジェクトのインスタンスをロックしています。あなたの例では:
public synchronized void setCount(int count){
これは、特定のインスタンスをロックすることと同じであり、Counter次と同等です。
public void setCount(int count){
synchronized (this) {
...
したがって、2つCounterのオブジェクトがcounter1ありcounter2、1つのスレッドが呼び出しcounter1.getCount()ていて、もう1つのスレッドがcounter2.getCount()同時に呼び出している場合、それらは両方とも同じClassオブジェクトをロックし、一方が他方をブロックします。
しかし、2つのスレッドが代わりに呼び出しcounter1.setCount(...)ていて、それぞれcounter2.setCount()異なるオブジェクトをロックしている場合。それらは互いにブロックしません。counter1counter2
前述のように、セッターとゲッターに非対称性があるのは非常に悪い形式であり、どちらかが非対称であるのは珍しいことstaticです。
これは、getCount()が呼び出されると、クラス全体がロックされているため、別のスレッドがsetCount()にアクセスできないことを意味しますか?
いいえ。getCount()が呼び出されCounter.classた場合はロックされ、setCount(...)が呼び出されたcounter1場合counter2はロックされます。ロックがスレッドをブロックするのは、同じオブジェクトが別のスレッドによってロックされている場合のみです。ロックがオンになっているからといって、ある種の超クラスのロックがあることを意味するわけではありCounter.classません。別のスレッドをブロックするのは、それがロックしすぎている場合のみCounter.classです。
動作方法に関するSunの優れたドキュメントをsynchronized少し読んでみます。