2012-02-28 96 views
4

如果我有一些同步的方法,其中有些是靜態的,他們中的一些不是一類:同步靜態方法

public class A { 
    public static void synchronized f1() {} 
    public void synchronized f2() {} 
} 

當一個線程調用F1會發生什麼()和第二呼叫F2( ),這意味着它們是如何彼此同步的。以及如果一個胎面調用f1()和f1()調用f2()會發生什麼?

+2

你最終會陷入混亂 – kosa 2012-02-28 17:54:47

+0

不久之後可能最終會陷入僵局。 – 2012-02-28 18:24:22

回答

9

他們彼此都同步。靜態方法在A.class上同步,第二個在this上同步。因此,它是(幾乎)就好像你寫:

public class A { 
    public static void f1() { 
     synchronized(A.class) { 
      ... 
     } 
    } 

    public void f2() { 
     synchronized(this) { 
      ... 
     } 
    } 
} 

,如果一個胎面調用F1()和F1()調用F2會發生什麼()

然後該線程將擁有監測f2期間。在做這件事之前,你應該小心,好像你在其他地方以相反的順序取出鎖,你將會陷入僵局。

就我個人而言,我會敦促你完全避免同步方法。相反,在專用,最終字段上同步,這些字段僅用於鎖定的只有。這意味着,只有你類是能夠獲得相關的顯示器,讓您可以更仔細地考慮,而持有鎖所發生的原因,而避免死鎖等

+0

如果我有2個線程:T1,T2。 T2調用f2(){... f1(); ...},T1調用f1 {... notifyAll();等待(); ...}。如果T1叫wait(); ,從T2調用的f1()中的notifyAll()會喚醒T1? – Michael 2012-02-28 18:24:23

+0

@Michael:從評論中很難跟蹤這些代碼,問題也不清楚。如果您有*特定*問題,我建議您將其編輯到原始文章中(或者開始一個新文章)。 – 2012-02-28 18:29:41

1

一個同步靜態方法是在該類的同步相應的Class對象,因此它與實例方法所使用的不同。顯然,靜態方法無權訪問this。因此,您的f1()和f2()方法不會相互同步,只能針對該類的其他靜態或其他實例方法進行同步。