2013-03-04 16 views
5

以下のコードでデッドロックが発生するのはなぜですか?私はgetNumber()を呼び出すと、クラスTestのオブジェクトがロックされているので、getNumber2(。)にアクセスできなくてすべきです。同じオブジェクトの同期メソッドから同期メソッドを呼び出す

class Test() { 
    synchronized int getNumber(int i){ 
     return getNumber2(i); 
    } 

    synchronized int getNumber2(int i) { 
     return i; 
    } 

    public static void main(String[] args) { 
     System.out.println((new Test()).getNumber(100)); 
    } 
} 

出力:ロックが、それは同じスレッドで複数回取得することができることを意味する、再入ですので

100 
+0

同様の投稿:http://stackoverflow.com/questions/5798637/is-it-safe-to-call-a-synchronized-method-from-another-synchronized-method – Walls

+0

はい質問は同じです文脈は全く異なっています。この質問では、デッドロック、それ以外についてはスレッドセーフについての質問です。 – Lovera

答えて

19

これがあります。 Java tutorialから

リエントラント同期スレッドが別のスレッドが所有しているロックを取得することはできません

リコール。しかし、スレッドはすでに所有しているロックを取得できます。スレッドが同じロックを複数回取得できるようにすると、再入可能な同期が可能になります。これは、同期コードが直接的または間接的に同期コードを含むメソッドを呼び出し、両方のコードセットが同じロックを使用する状況を示します。再入可能な同期がなければ、同期コードは、スレッド自体がブロックするのを避けるために、さらに多くの予防策を講じなければなりません。

JLSの関連部分は§17.1. Synchronizationある:

Javaプログラミング言語は、スレッド間で通信するための複数のメカニズムを提供します。これらのメソッドの最も基本的なものは、モニターを使用して実装される同期です。 Javaの各オブジェクトは、スレッドがロックまたはロック解除できるモニターに関連付けられています。一度に1つのスレッドだけがモニタにロックを保持できます。そのモニターをロックしようとする他のスレッドは、そのモニター上でロックを取得できるまでブロックされます。 スレッドtは、特定のモニターを複数回ロックすることがあります。それぞれのロック解除は、1つのロック操作の効果を逆転させます。

4

スレッドが同期メソッドを入力するとき、どのようなそれがないことは、それがthisのロックを持っていることをチェックして、それがない場合、それは持ってできるようになるまで、そして、それは待つので、デッドロックにつながりませんロックして取得します。

スレッドが2番目の同期メソッドに入ると、既にオブジェクトがthisにロックされているため、ブロックせずにメソッドに入ることができます。

関連する問題