【问题标题】:How class level lock is acquired如何获取类级别锁
【发布时间】:2013-07-22 09:05:45
【问题描述】:
public synchronized int getCountOne() {
        return count++;
 }

就像上面的代码同步方法在功能上等同于在方法体周围有一个synchronized (this) block。对象“this”没有被锁定,而是对象“this”被用作mutex,并且主体被阻止与同样在“this”上同步的其他代码部分同时执行。

基于类似的理由,当我们获得一个类级别的锁时,它被用作mutex。就像我们有一个函数一样

public static synchronized int getCountTwo() {
        return count++;
 }

显然两个线程可以同时获得getCountOne(object level lock)和getCountTwo(class level lock)的锁。所以 getCountOne 类似于

public int getCountOne() {
     synchronized(this) {
          return count++;
     }
 }

有没有 getCountTwo 的等价物?如果没有,使用什么标准来获得 Class 级别的锁?

【问题讨论】:

    标签: java static synchronization locking


    【解决方案1】:

    基于类似的理由,当我们获得类级锁时,什么被用作互斥锁

    类对象本身将用作互斥体。 static synchronized 方法的等效同步块如下所示:

    public static int getCountTwo() {
         synchronized(ClassName.class) {
              return count++;
         }
    }
    

    ClassName 是包含该方法的类的名称。

    JLS Section §8.4.3.6:

    同步方法在执行之前获取监视器(第 17.1 节)。

    对于类(静态)方法,与该类关联的监视器 使用方法类的对象

    对于实例方法,与 this 关联的监视器(对象 调用该方法的对象)。

    强调我的。

    【讨论】:

    • 感谢您的精彩解释
    【解决方案2】:

    对象级锁定:

    当您想要同步非静态方法或非静态代码块时,对象级锁定是一种机制,这样只有一个线程能够在给定的类实例上执行代码块。应该始终这样做以使实例级数据线程安全。这可以如下完成:

    public class DemoClass 
    { 
      public synchronized void demoMethod(){} 
    } 
    
    or 
    
    public class DemoClass 
    { 
      public void demoMethod(){ 
      synchronized (this) 
      { 
       //other thread safe code 
      } 
     } 
    } 
    
    or 
    
    public class DemoClass 
    { 
      private final Object lock = new Object(); 
      public void demoMethod(){ 
      synchronized (lock) 
     { 
      //other thread safe code 
     } 
    } 
    

    类级锁定:

    类级别锁定可防止多个线程在运行时的所有可用实例中进入同步块。这意味着如果在运行时有 100 个 DemoClass 实例,那么一次只有一个线程能够在任何一个实例中执行 demoMethod(),而所有其他实例都将被其他线程锁定。应该始终这样做以使静态数据线程安全。

    public class DemoClass 
    { 
      public synchronized static void demoMethod(){} 
    } 
    
    or 
    
    public class DemoClass 
    { 
      public void demoMethod(){ 
      synchronized (DemoClass.class) 
      { 
       //other thread safe code 
      } 
     } 
    } 
    
    or 
    
    public class DemoClass 
    { 
     private final static Object lock = new Object(); 
     public void demoMethod(){ 
     synchronized (lock) 
      { 
       //other thread safe code 
      } 
     } 
    }
    

    【讨论】:

    • 不回答这个问题:“什么被用作互斥体”?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-25
    • 2022-01-12
    相关资源
    最近更新 更多