2011-11-21 92 views
2

如何在編寫Java同步代碼時同時運行靜態和非靜態Java同步方法?java中的方法同步

public class Counter{ 

    private static count = 0; 

    public static synchronized getCount() 
    { 
     return this.count; 
    } 

    public synchronized setCount(int count) 
    { 
     this.count = count; 
    } 
} 
+0

您可以發表一個代碼示例,使問題更加精確嗎? – wrschneider

+0

@ wrschneider99現在請給我答案 – PENNY

+0

爲什麼你的getter是一個靜態方法,但你的setter是一個實例方法? –

回答

2

我仍然不明白這個問題,我很困惑你的代碼示例。你有靜態方法引用「this.counter」,但「計數器」是靜態的。

在任何情況下,重新狀態的一些其他的答案,認爲:

public static synchronized classMethod() {....} 
public synchronized instanceMethod() {...} 

「同步」在每種情況下是指兩個不同的東西。在靜態的classMethod上,「synchronized」適用於類對象的(Counter.class)監視器,而instanceMethod的「synchronized」適用於對象實例的(「this」)監視器。

因此,classMethod和instanceMethod不會互相鎖定。 instanceMethod會阻塞另一個非靜態同步方法,而classMethod會阻塞其他靜態同步方法。

7

靜態方法在類對象上同步,而非靜態方法在它們被調用的類的特定實例上同步。因此它們可以並行執行,因爲它們通常在不同的對象上同步。

在下面的例子staticMethod1是基本相同staticMethod2method1僅僅是後者的版本使用上,他們明確地同步對象一樣method2

class MyClass 
{ 
    static synchronized void staticMethod1() 
    { 
     doSomething(); 
    } 

    static void staticMethod2() 
    { 
     synchronized(MyClass.class) 
     { 
      doSomething(); 
     } 
    } 

    synchronized void method1() 
    { 
     doSomething(); 
    } 

    void method2() 
    { 
     synchronized(this) 
     { 
      doSomething(); 
     } 
    } 
} 
2

如果你有類「測試「,則非靜態同步this(Test類實例)和靜態同步Test.class(即java.lang.Class類實例)。所以,是的,它是完全不同的對象,因此它們可以並行運行。

2

Java同步基於monitor的概念。每個對象都可以是一個監視器,每一段同步代碼都指向一個監視器對象。對於同步靜態方法,這是類對象。對於同步實例方法,它是實例。對於同步塊,顯式指定監視器對象。

重要的一點:如果兩個線程在同一監視器對象上不同步,它們可以並行執行一段同步代碼。如果您有一個同步的靜態方法和一個同步實例方法,則它們不能具有相同的監視器,因此它們可以並行執行。

1

方法沒有鎖定,對象被鎖定。您可以在使用不同對象的相同同步方法中擁有兩個線程。但是,不能讓兩個線程運行同一對象的不同同步方法。

靜態方法和非靜態方法不鎖定同一個對象。

+0

True - 將同步方法簽名等同於將整個方法主體封裝在「synchronized(this){...}」或「synchronized(Foo.class){...}」中,具體取決於方法是靜態與否。如果在方法體中顯式使用synchronized,則可以更精確地控制哪個對象的監視器將用於鎖定。 – wrschneider

+1

此外,如果您正等待(),您可以在同步塊中擁有任意數量的線程,但只有一個正在運行。 –