如果我有一个包含许多同步方法的类,其中一些是静态的,而其中一些不是:
public class A {
public static void synchronized f1() {}
public void synchronized f2() {}
}
当一个线程调用f1()而第二个调用f2()时会发生什么,这意味着它们如何彼此同步。如果一个胎面调用f1()和f1()调用f2()会发生什么?
答案 0 :(得分:9)
他们根本没有彼此同步。静态方法在A.class
上同步,第二个在this
上同步。所以它(几乎)好像你写的那样:
public class A {
public static void f1() {
synchronized(A.class) {
...
}
}
public void f2() {
synchronized(this) {
...
}
}
}
如果一个胎面调用f1()和f1()调用f2()
会发生什么
然后该线程将在f2
期间拥有两个监视器。在你这样做之前你应该小心,好像你在其他地方以相反的顺序取出锁,你将陷入僵局。
就个人而言,我会敦促你完全避免使用同步方法。而是在用于锁定的仅的私有,最终字段上进行同步。这意味着只有您的类能够获取相关的监视器,因此您可以更加仔细地了解锁定时发生的事情,并避免死锁等。
答案 1 :(得分:1)
同步静态方法在 Class 对象上进行同步,而不是在实例上进行同步。
f1()
和f2()
可以由两个单独的线程调用,并且可以同时执行。
请参阅:http://java.sun.com/docs/books/jls/third_edition/html/classes.html#260369
答案 2 :(得分:1)
同步静态方法在类的相应Class对象上同步,因此它与实例方法使用的锁不同。显然,静态方法无法访问this
。因此,您的f1()和f2()方法不会相互同步,仅针对该类的其他静态或其他实例方法。