オブジェクトレベルのロックとクラスレベルのロックとはどういう意味ですか?
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()
異なるオブジェクトをロックしている場合。それらは互いにブロックしません。counter1
counter2
前述のように、セッターとゲッターに非対称性があるのは非常に悪い形式であり、どちらかが非対称であるのは珍しいことstatic
です。
これは、getCount()が呼び出されると、クラス全体がロックされているため、別のスレッドがsetCount()にアクセスできないことを意味しますか?
いいえ。getCount()
が呼び出されCounter.class
た場合はロックされ、setCount(...)
が呼び出されたcounter1
場合counter2
はロックされます。ロックがスレッドをブロックするのは、同じオブジェクトが別のスレッドによってロックされている場合のみです。ロックがオンになっているからといって、ある種の超クラスのロックがあることを意味するわけではありCounter.class
ません。別のスレッドをブロックするのは、それがロックしすぎている場合のみCounter.class
です。
動作方法に関するSunの優れたドキュメントをsynchronized
少し読んでみます。