クラスに複数のsynchronizedメソッド(両方staticとinstance)がある場合、私が知る限り、Javaは一度に実行するそのようなメソッドは1つだけです。しかし、スレッドがオブジェクトインスタンス(またはクラス)のロックを取得した場合、そのオブジェクト内でsynchrozedメソッドに入り、同じオブジェクトの別の同期されたメソッドを呼び出します。私は言うことを意味します:
Class AA
{
..
..
synchronized void X()
{
Y();
}
synchronized void Y()
{
..
..
}
メソッドXを実行しているスレッドが永久にブロックすることはありますか? JavaはメソッドXとメソッドYの両方を同時に実行することを許可しないので?
Javaでは、synchronized
ロックは 再入可能 です。
あるいは、スレッドがオブジェクトのロックをすでに保持している場合は、それ自体で待機する必要はありません。
synchronized
のドキュメントを注意深く読むと、スレッドがロックを取得すると、必要なだけ何度でも再取得できることが明示されていることがわかります。
Java言語仕様によると:
8.4.3.6項「同期メソッド」は、synchronized
キーワードがモニターを取得することを示しています。参照: http://docs.Oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.3.6
「17.1同期」のセクションでは、スレッドtが特定のモニターを複数回ロックする可能性があると述べています。 http://docs.Oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.1 を参照してください
したがって、スレッドがロックを取得した場合に待機する必要があるのは、otherスレッドのみです。同じスレッドが待機することなく、ロックを再取得できます。
Java同期は、同期されたメソッドのインスタンスに再帰的ロックを使用します。これは、各インスタンスに再帰的ロックがあり、@ synchronizedがその再帰的ロックをロックするようなものです(JVMは明らかにより賢い方法を使用しています)。したがって:
@synchronizedクラスメソッドの場合、クラス自体の再帰的ロックが使用されます。クラスはファーストクラスオブジェクトであるため、上記と同じルールが適用されます。
Javaでは、このようなメソッドを一度に1つだけ実行できます
まあ、それは絶対に真実ではありません。まず、10個のスレッドが10個の異なるインスタンスの10個の同期されたメソッドを呼び出すことができ、それらすべてを最初に実行できます。同期された各メソッドは、他のインスタンスの他の同期されたメソッドを呼び出すことができ、@ synchronizedメソッドで使用されない限り、これも機能します。また、各@synchronizedメソッドは、同じインスタンスの@synchronizedメソッドを好きなだけ再帰的に呼び出すことができます。
制限は次のとおりです。2つのスレッドが同じインスタンスの@synchronizedメソッドを同時に実行したり、同じクラスの@synchronizedクラスメソッドを同時に実行したりすることはできません。