Java .class的Java同步块


Answers:


144

片段synchronized(X.class)使用类实例作为监视器。由于只有一个类实例(在运行时表示类元数据的对象),因此该块中可以有一个线程。

synchronized(this)该块由实例保护。对于每个实例,只有一个线程可以进入该块。

synchronized(X.class)用于确保该块中恰好有一个线程。synchronized(this)确保每个实例只有一个线程。如果这样会使块中的实际代码具有线程安全性,则取决于实现。如果mutate,则仅实例的状态synchronized(this)就足够了。


6
“尽可能多的线程可以根据实例进入该块”意味着第二种形式充当了信号量,这是不正确的。您应该这样说:“ synchronized(this)确保只有一个线程可以为该类的给定实例输入该块”。
2010年

已更正。我打算这么说。
Thomas Jung

2
什么是类实例与实例?
曾伟石

因此,如果您有一个静态方法,而又不想同步其所有主体,则我们的synced(this)不好,取而代之的是synced(Foo.class)。那正确吗?
krupal.agile

84

要添加其他答案:

static void myMethod() {
  synchronized(MyClass.class) {
    //code
  }
}

相当于

static synchronized void myMethod() {
  //code
}

void myMethod() {
  synchronized(this) {
    //code
  }
}

相当于

synchronized void myMethod() {
  //code
}

12
我花了二读才发现前两个示例的关键字为“ static”。只是向其他可能已经看到并错过它的人指出这一点。没有static关键字,前两个示例将是不同的。
kurtzbot 2014年

1
这些例子不一样!当线程试图调用同步方法时,这些同步方法会作为一个空洞“同步”。另一方面,这些块可以在它们之上和之下具有代码,这些代码可以从多个线程执行。它们仅在块内同步!那不一样!
JacksOnF1re

公共静态Singleton getInstance(){如果(instance == null){已同步(Singleton.class){instance = new Singleton(); 返回实例;}
JacksOnF1re

2
整点是,有就是外面没有代码synchronized块。这使它们等效。如果您更改一个示例,则它们确实不再相同。
乔恩

22

不,第一个将锁定的类定义MyClass,而不是它的所有实例。但是,如果在实例中使用,这将有效地阻止所有其他实例,因为它们共享一个类定义。

第二个将仅锁定当前实例。

关于这是否使您的对象线程安全,这是一个更为复杂的问题-我们需要查看您的代码!


1
是的,MyClass.class可以是任何静态变量,并且具有相同的效果。
pstanton 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.