synchronized(this)和synchronized(ClassName.class)有什么区别?

时间:2012-01-29 19:47:38

标签: java synchronized

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

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)之间真的有区别吗?

6 个答案:

答案 0 :(得分:26)

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

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

synchronized(SomeClass.class)在当前对象的上同步(或者如果有人希望的话,则为另一个类),因此一次只有一个线程可以访问任何实例那个班。

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

答案 1 :(得分:6)

每个实例的

this都不同 ClassName.class不是。

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

答案 2 :(得分:3)

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

  

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

答案 3 :(得分:2)

每个java Object都可以拥有一个锁。这个锁一次最多可以保存一个线程,任何其他线程都必须等待获取同一个对象的锁。

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

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

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

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

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

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

您引用的线程声明使用私有实例是一种更好的做法,因为直接在对象实例上进行同步可能会很危险。为此你可以使用:

class MySharedResourceClass {

    private SomeClass lock = new SomeClass();

    public doSomething() {
        synchronized (lock) {
            // Do something here
        }
    }
}