2012-01-29 66 views

回答

23

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

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

synchronized(SomeClass.class)对当前对象(或其他类如果希望)的类同步,以便一次仅一个线程可以访问该类的任何实例。

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

+1

+1。这给类和对象锁之间的更清晰。我没有发现比这更好的东西。 *简单易懂* – Ravi 2017-05-21 16:21:03

5

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

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

3

​​关键字适用于class锁类,并且当它应用于this锁定当前对象实例。从Java语言规范中,部分8.4.3.6, 'synchronized Methods'

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

1

这些是2个不同的目的是锁定: “这”是指当前实例的上下文,因此创建多个实例,如果例如,每个线程使用不同的实例将不会产生影响,在其锁定。 'this'只能在非静态上下文中引用。
'class'是Java Class的一个静态成员,它只有一个实例。您可以在静态和非静态上下文中锁定它。

1

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

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

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

单独使用​​或者作为方法修饰符,还会同步实例的信号量,该信号通常用于防止多个线程访问该实例作为共享资源(即列表)。

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

class MySharedResourceClass { 

    private SomeClass lock = new SomeClass(); 

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

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

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

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

相关问题