为什么 synchronized 块比 synchronized 方法更好?

新手上路,请多包涵

我已经开始学习线程同步。

同步方法:

 public class Counter {

   private static int count = 0;

   public static synchronized int getCount() {
      return count;
   }

   public synchronized setCount(int count) {
      this.count = count;
   }

}

同步块:

 public class Singleton {

   private static volatile Singleton _instance;

   public static Singleton getInstance() {
      if (_instance == null) {
         synchronized(Singleton.class) {
            if (_instance == null)
               _instance = new Singleton();
         }
      }
      return _instance;
   }
}

我什么时候应该使用 synchronized 方法和 synchronized 块?

为什么 synchronized 块优于 synchronized 方法?

原文由 Sabapathy 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 619
2 个回答

这不是更好的问题,只是不同的问题。

当您同步一个方法时,实际上是在同步对象本身。在静态方法的情况下,您正在同步到对象的类。所以下面两段代码的执行方式是一样的:

 public synchronized int getCount() {
    // ...
}

这就像你写的一样。

 public int getCount() {
    synchronized (this) {
        // ...
    }
}

如果你想控制同步到一个特定的对象,或者你只想让一个方法的 一部分 同步到该对象,那么指定一个 synchronized 块。如果在方法声明中使用 synchronized 关键字,它会将整个方法同步到对象或类。

原文由 Erick Robertson 发布,翻译遵循 CC BY-SA 3.0 许可协议

不同之处在于获取锁的方式:

  • synchronized 方法获取整个对象的锁。这意味着当方法由一个线程运行时,其他线程不能在整个对象中使用任何同步方法。

  • synchronized 块在 synchronized 关键字后的括号之间获取对象中的锁。这意味着在同步块退出之前,没有其他线程可以获取锁定对象的锁。

所以如果你想锁定整个对象,使用同步方法。如果你想让其他线程可以访问对象的其他部分,请使用同步块。

如果仔细选择锁定的对象,同步块将导致更少的争用,因为整个对象/类都没有被阻塞。

这同样适用于静态方法:同步静态方法将获取整个类对象的锁,而静态方法内部的同步块将获取括号之间对象的锁。

原文由 Angular University 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题