2012-02-28 77 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()方法不会相互同步,只能针对该类的其他静态或其他实例方法进行同步。