2011-07-13 5 views
1

デッドロックシナリオは、以下に示すStaticDeadlockクラスとして要約できます。スタティックブロック内のthread.join()によるデッドロック

この単純なプログラムは、 o.getClass()でフリーズします。何が起こったのか私の推測ですが、誰かがそれをよりよく説明できますか?

1)プログラムはStaticDeadlock静的ブロックに入る

2)スレッド開始

3)メインスレッドはスタティックを終えることができないため、終了するスレッド待ちに置かれ

4)スレッドそれアクセス StaticDeadlock.o 内部しかしStaticDeadlockの静的ブロックがnブロックまだ完了していません。したがって、プログラムはフリーズしますか?

public class StaticDeadlock 
    { 
     private static final Object o = new Object(); 

     static { 
      MyThread thread = new MyThread(); 
      thread.start(); 

      try { 
       thread.join(); 
      } 
      catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     public static void main (String[] args) 
     { 
      System.out.println("all is well."); 
     } 

     static class MyThread extends Thread 
     { 
      @Override 
      public void run() 
      { 
       System.out.println("inside mythread"); 
       o.getClass(); 
      } 
     } 

    } 

答えて

7

はい、それはかなりです。新しいスレッドは、静的メンバーにアクセスする前に、クラス初期化子StaticDeadlockが完了するのを待機しています。これらの工程、特に、詳細はsection 12.4.2 of the Java Language Specificationを見る

  1. 同期(14.19)初期化するクラスまたはインタフェースを表すクラスオブジェクト上。これは、現在のスレッドがそのオブジェクトに対するロックを取得できるようになるまで待つことを含む(§17.1)。

  2. 他のスレッドによってクラスまたはインタフェースの初期化が進行中の場合は、このClassオブジェクト(ロックを一時的に解除する)を待機します。現在のスレッドが待機から目覚めたら、この手順を繰り返します。

  3. 現在のスレッドによるクラスまたはインタフェースの初期化が進行中の場合、これは初期化の再帰的要求でなければなりません。クラスオブジェクトのロックを解放し、正常に完了します。

  4. クラスまたはインターフェイスがすでに初期化されている場合、これ以上の操作は必要ありません。クラスオブジェクトのロックを解放し、正常に完了します。

最初のスレッドがロックを持っており、それを解放しないので、それも、第二のスレッドで過去のステップ1を取得することはできません。クラス初期化子が完了するまでoの値が第2のスレッドの待機を行います必要がをやって、最初のスレッドがあるので、もちろん起こらないであろう - 問題を引き起こすgetClass()を呼び出していないことを

注意2番目のスレッドが終了するのを待つ。

関連する問題