【问题标题】:synchronized static methods同步静态方法
【发布时间】:2012-02-28 17:49:13
【问题描述】:

如果我有一个包含多个同步方法的类,其中一些是静态的,而另一些则不是:

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

当一个线程调用 f1() 和第二个调用 f2() 时会发生什么,这意味着它们如何相互同步。如果一个胎面调用 f1() 而 f1() 调用 f2() 会发生什么???

【问题讨论】:

  • 可能很快就会陷入僵局。

标签: java parallel-processing synchronized


【解决方案1】:

它们完全彼此同步。静态方法在A.class上同步,第二个在this上同步。所以它(几乎)就像你写的那样:

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

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

如果一个踏板调用 f1() 而 f1() 调用 f2() 会发生什么

那么该线程将在f2 期间拥有两个 监视器。在做这件事之前你应该小心,如果你在其他地方以相反的顺序取出锁,你会得到一个死锁。

我个人建议您完全避免使用同步方法。相反,在私有的、最终的字段上进行同步,这些字段用于锁定。这意味着只有您的类能够获取相关的监视器,因此您可以更仔细地推断在持有锁时发生的情况,并避免死锁等。

【讨论】:

  • 如果我有 2 个线程:T1、T2。 T2 调用 f2(){ ... f1(); ...},T1 调用 f1{... notifyAll();等待(); ...}。如果 T1 调用了 wait(); ,f1()中的notifyAll(),被T2调用会唤醒T1吗?
  • @Michael:仅从 cmets 很难遵循该代码,而且问题也不清楚。如果您有具体的问题,我建议您将其编辑到您的原始帖子中(或开始一个新帖子)。
【解决方案2】:

同步的静态方法在 Class 对象上同步,而不是在实例上同步。

f1()f2() 可以被两个单独的线程调用,并同时执行。

见:http://java.sun.com/docs/books/jls/third_edition/html/classes.html#260369

【讨论】:

    【解决方案3】:

    同步的静态方法在类的相应 Class 对象上同步,因此它是与实例方法使用的不同的锁。显然,静态方法无权访问this。因此,您的 f1() 和 f2() 方法不会相互同步,仅与类的其他静态或其他实例方法同步。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-06
      • 2011-03-20
      相关资源
      最近更新 更多