2011-10-18 16 views
1

私はIBM developerworksサイトからのスレッドチュートリアルを読んでいました。その中で、彼らはsynchronizedキーワードと、コードのブロックではなく、実際のオブジェクトによって同期されたコードブロックがどのようにロックされるかについて話しました。著者が同期として静的クラスのThingiesetLastAccess方法が記載されているにもかかわらず、それらは異なる値を使用しているため、その下に定義された2つのスレッドがそれぞれ、同時にsetLastAccessを呼び出すことができると述べている次のコードで例えば同期化されたキーワードとJavaの静的クラス

、あなたのために。しかし、仮面が静的であれば、彼らは同じ価値を使用しているという意味ではありませんか?

同じオブジェクトを参照していても、変数名が異なるだけでよい場合はありますか?

public class SyncExample { 
    public static class Thingie { 
     private Date lastAccess; 
     public synchronized void setLastAccess(Date date) { 
      this.lastAccess = date; 
     } 
    } 
    public static class MyThread extends Thread { 
     private Thingie thingie; 
     public MyThread(Thingie thingie) { 
      this.thingie = thingie; 
     } 
     public void run() { 
      thingie.setLastAccess(new Date()); 
     } 
    } 
    public static void main() { 
     Thingie thingie1 = new Thingie(), 
     thingie2 = new Thingie(); 
     new MyThread(thingie1).start(); 
     new MyThread(thingie2).start(); 
    } 
} 
+1

私はそれが変数の名前に依存しないと確信しています。同期化は、変数ではなく実際のオブジェクトに対する呼び出しです。 –

+0

http://stackoverflow.com/questions/578904/how-do-synchronized-static-methods-work-in-javaに関連する – Gray

+0

私の答えはあなたを@larryqに助けましたか?もしそうなら、それを受け入れてください。 – Gray

答えて

4

あなたは、静的クラスで静的方法を混乱されています。 setLastAccessがstatic のメソッドの場合、​​とマークされている場合、ClassLoaderClassインスタンスがロックされます。ローダーごとに1つしかありません。メソッドが静的で同期されていた場合、スレッドは同じオブジェクトにロックされます。

ただし、あなたの例ではThingieクラスはメソッドではなく静的としてマークされています。 クラスのstaticキーワードは、Thingieが外部SyncExampleクラスに関連付けられていないことを意味します。ではありません。は、Thingieというインスタンスが1つしか存在せず、同期に影響しません。したがって、あなたの例では、setLastAccessに​​とマークされている場合、それはクラスThingiethis)のインスタンスでロックされています。 2つのインスタンス(thingie1thingie2)が存在するため、ロックは異なるオブジェクトにあります。明らかに、両方のスレッドがthingie1で渡された場合、それらは両方とも同じオブジェクトでロックされます。

+0

私は説明を感謝します。しかし、Thingieが静的クラスであることを考えると、2つのインスタンス(thingie1とthingie2)が存在する可能性がありますか?そうでない場合、setLastAccess()への2つの(同期された)呼び出しがThingieの同じインスタンスから呼び出されているとは限りませんか? – larryq

+0

あなたは私の答え@larryqを読んでいるかどうかわかりません。 'static'キーワードは単一インスタンスを意味するわけではありません。私の答えの2番目の段落と上記の "入れ子のクラス"のリンクを読んでください。 – Gray

+0

グレー - 説明とリンクのために多くの感謝。ネストされた静的クラスが表すものについての私の誤解。私はそれが外部クラスの静的メンバー(クラスであっても)であったため、直接インスタンス化できないと考えました。少なくとも、外部クラスに結び付けられた1つのインスタンスのみを返します。私は間違っていた。 – larryq

3

このコード:

class SomeClass { 
    public void setLastAccess(Date date) { 
     synchronized(this) { 
     } 
    } 
} 

そして、このコード:

class SomeClass { 
    public synchronized void setLastAccess(Date date) { 
    } 
} 

が同じである

class SomeClass { 
    public static synchronized void setLastAccess(Date date) { 
    } 
} 

は同じです

0

同期メソッドがインスタンスメソッドの場合、ロックは各オブジェクトで実行されます。 obj1とobj2の2つのオブジェクトがある場合、独自のインスタンスをロックしたメソッドを実行できます。

静的メソッドが同期されている場合、ロックはクラスオブジェクトに対して実行されます。したがって、最初の静的同期メソッドが実行されているときに、そのメソッドおよびその他の静的メソッドを実行することはできません。

関連する問題