.classのJava同期ブロック


102

このJavaコードはどういう意味ですか?それはのすべてのオブジェクトをロックしますMyClassか?

synchronized(MyClass.class) {
   //is all objects of MyClass are thread-safe now ??
}

そして、上記のコードがこれとどのように異なるか:

synchronized(this) {
   //is all objects of MyClass are thread-safe now ??
}

回答:


144

スニペットsynchronized(X.class)は、クラスインスタンスをモニターとして使用します。1つのクラスインスタンス(実行時のクラスメタデータを表すオブジェクト)しかないため、このブロックには1つのスレッドを含めることができます。

synchronized(this)ブロックインスタンスによって守られています。すべてのインスタンスで、ブロックに入ることができるスレッドは1つだけです。

synchronized(X.class)ブロックにスレッドが1つだけあることを確認するために使用されます。synchronized(this)インスタンスごとに1つのスレッドが存在することを確認します。これにより、ブロック内の実際のコードがスレッドセーフになるかどうかは、実装によって異なります。mutateの場合、インスタンスの状態のみsynchronized(this)で十分です。


6
「インスタンスの数だけスレッドがブロックに入る可能性がある」とは、2番目の形式がセマフォとして機能することを意味しますが、これは正しくありません。「synchronised(this)は、クラスの特定のインスタンスのブロックに入ることができるスレッドが1つだけであることを保証します」のように言う必要があります。
liwp

修正。そういうつもりでした。
Thomas Jung

2
クラスインスタンスとインスタンスとは何ですか?
Weishi Zeng

したがって、静的メソッドがあり、その本体のすべてを同期したくない場合は、同期(this)は適切ではなく、同期(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
最初の2つの例のキーワードが「静的」であることを理解するのに2回目の読みが必要でした。これを見て、見逃したかもしれない他の人にそれを指摘するだけです。staticキーワードがないと、最初の2つの例は同じになりません。
kurtzbot 14

1
これらの例は同等ではありません!同期されたメソッドは、スレッドがメソッドを呼び出そうとすると、穴として「同期」されます。一方、ブロックには、複数のスレッドから実行できるコードの上下にコードを含めることができます。ブロック内でのみ同期します!それは同じではありません!
JacksOnF1re 2018年

public static Singleton getInstance(){if(instance == null){synchronized(Singleton.class){instance = new Singleton(); インスタンスを返す。}
JacksOnF1re 2018年

2
重要なのは、ブロックの外側にコードないということですsynchronized。それはそれらを同等にします。1つの例を変更すると、実際には同じではなくなります。
Jorn

22

いいえ、最初のクラスはのクラス定義をロックしますがMyClass、そのすべてのインスタンスをロックするわけではありません。ただし、インスタンスで使用すると、他のすべてのインスタンスが単一のクラス定義を共有するため、これらのインスタンスは事実上ブロックされます。

2番目は、現在のインスタンスのみをロックします。

これによりオブジェクトがスレッドセーフになるかどうかについては、これははるかに複雑な質問です。コードを確認する必要があります。


1
はい、MyClass.classは任意の静的変数で、同じ効果があります。
10
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.