【问题标题】:What is the difference between synchronized(this) and synchronized(ClassName.class)?synchronized(this) 和 synchronized(ClassName.class) 有什么区别?
【发布时间】:2012-02-21 19:02:57
【问题描述】:

我在某处读到 synchronized(this) 应该避免使用 various reasons。然而,我遇到的一些可敬的代码在构造函数中使用了以下代码:

public SomeClass(Context context) {
  if (double_checked_lock == null) {
    synchronized (SomeClass.class) {
      if (double_checked_lock == null) {
        // some code here
      }
    }
  }
}

synchronized(this)synchronized(SomeClass.class) 之间真的有区别吗?

【问题讨论】:

    标签: java synchronized


    【解决方案1】:

    synchronized(this)是在当前对象上同步的,所以每个实例只有一个线程可以访问,但是不同的线程可以访问不同的实例。例如。每个线程可以有一个实例。

    这通常有助于防止多个线程同时更新一个对象,这可能会产生不一致的状态。

    synchronized(SomeClass.class) 在当前对象的 class 上同步(或另一个类,如果需要),因此一次只有一个线程可以访问该对象的 any 实例类。

    这可用于保护在类的所有实例(可能是实例缓存或实例总数的计数器)之间共享的数据不会进入不一致状态。

    【讨论】:

    • +1。这使类和对象锁之间更加清晰。我没有找到比这更好的东西。 简短易懂
    【解决方案2】:

    每个 java 对象都可以有一个锁。这个锁一次最多只能被一个线程持有,任何其他线程都必须等待才能获得同一个对象的锁。

    • synchronized(this)为当前线程获取实例this的锁。该方法可以在不同的实例上并行运行(不同的值,因此不同的锁)

    • synchronized(SomeClass.class)获取SomeClass的全局类对象的锁。只有一个方法实例可以运行,因为所有对象实例都锁定在同一个全局对象上(同一个锁)。

    【讨论】:

      【解决方案3】:

      synchronized(this) 在对象的实例上同步。

      synchronized(SomeClass.class)使用代表 SomeClass 的 Class 对象的实例,它对于同一类加载器中的所有实例都是全局的。

      因此,这些是具有不同语义的不同构造。

      单独使用synchronized,或作为方法修饰符,也会在实例的信号量上进行同步,这通常用于防止作为共享资源(即列表)访问该实例的多个线程之间的争用。

      您引用的线程指出,使用私有实例是一种更好的做法,因为直接在您的对象实例上同步可能很危险。为此,您将使用:

      class MySharedResourceClass {
      
          private SomeClass lock = new SomeClass();
      
          public doSomething() {
              synchronized (lock) {
                  // Do something here
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        这些是要锁定的 2 个不同对象: 'this' 指的是当前实例上下文,因此创建多个实例将不起作用,例如,如果每个线程使用不同的实例并锁定它。 'this' 只能在非静态上下文中引用。
        “类”是 Java 类的静态成员,并且只有一个实例。您可以在静态和非静态上下文中锁定它。

        【讨论】:

          【解决方案5】:

          synchronized 关键字,当应用于类上的 class 锁时,以及应用于当前对象实例上的 this 锁时。来自 Java 语言规范,8.4.3.6, 'synchronized Methods' 部分:

          同步方法在执行之前获取一个监视器(第 17.1 节)。对于类(静态)方法,使用与方法类的 Class 对象关联的监视器。对于实例方法,使用与 this(调用该方法的对象)关联的监视器。

          【讨论】:

            【解决方案6】:

            this 对于每个实例都是不同的。
            ClassName.class 不是。

            因此,synchronized(this) 将允许多个实例同时运行。

            【讨论】:

              猜你喜欢
              • 2015-01-30
              • 1970-01-01
              • 1970-01-01
              • 2015-03-25
              • 2012-02-05
              • 2011-03-31
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多