【问题标题】:syncronized block inside static method will acquire Class level lock or Object level lock静态方法中的同步块将获取类级别锁或对象级别锁
【发布时间】:2019-12-31 05:55:37
【问题描述】:

在下面的代码 sn-p 中,我有一个问题。 线程将获得类级锁或对象级锁?

private static Object lock=new Object();
private static Object lock2=new Object();

public static void m1(){
synchronized(lock){
//statements
}
}

public static void m2(){
synchronized(lock2){
//statements
}
}

【问题讨论】:

  • 您已获得lock 对象的锁定。所以它将锁定该对象而不是类级别
  • 感谢 Ashish,我很困惑,无论是 Object 类被锁定还是 Object 的对象在静态方法中被锁定,线程需要类级锁定
  • 只有当静态方法本身是同步的或者你使用了synchronized (EnclosingClass.class) { ... }时,它才会使用封闭类的Class对象。
  • @Slaw 所以这是我的一个疑问,对象与静态上下文无关,然后线程将获取对象上的锁定,或者在我的示例中,它将锁定在“锁定”变量上而不是对象上跨度>
  • @Mohdshaban - 请参阅下面的答案。也许它会帮助你消除疑虑

标签: java multithreading synchronized


【解决方案1】:

每个对象都有一个“监视器”。当您使用同步块时,您指定要在其监视器上同步的实例。除了同步的,还有同步的方法。同步 instance 方法将获取调用该方法的实例的监视器,而同步 static 方法将获取封闭类的 java.lang.Class 对象的监视器.

public class Foo {

  private static final Object STATIC_LOCK = new Object();
  private final Object instanceLock = new Object();

  public static void bar() {
    synchronized (STATIC_LOCK) { // acquires monitor of "STATIC_LOCK" instance
      // guarded code
    }
  }

  public static synchronized void baz() { // acquires monitor of "Foo.class" instance
    // guarded code
  }

  public void qux() {
    synchronized (instanceLock) { // acquires monitor of "instanceLock" instance
      // guarded code
    }
  }

  public synchronized void quux() { // acquires monitor of "this" instance
    // guarded code
  }
}

【讨论】:

    【解决方案2】:

    您已在 synchronized 代码块中明确使用 Object 类实例作为 monitor 对象,这意味着它将仅锁定那些 objects

    当您将函数定义为staticsynchronized 时,代码块使用类本身作为监控对象。因为当您定义静态函数时,该函数属于类本身,这意味着您不需要类实例来调用此类函数。因此,如果一个静态函数被定义为synchronized,那么它在多线程环境中的执行将需要锁定所有此类线程中的某个公共监视器对象,在这种情况下就是class 本身。

    注意 - 每个类定义本身都是 java.lang.Class

    的一个实例

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 2014-07-29
      相关资源
      最近更新 更多