2011-08-09 12 views
2

Javaでループしたサービスを同期的に開始するコードを実装しようとしています。アイデアは、// STARTERのコメントのコードはService.go()メソッドの一部と見なされるべきであるので、サービスが開始しなければ、私は例外を同期して再スローしたいと思います。そのコードは、を試して実行を試み、問題がなければその実行フローがあるポイントに達するまで待ってから、go()メソッドが終了してスレッドが実行されます。私のgo()メソッドからスレッドのrun()メソッドで捕捉された例外を再スローすることができます。ここでは正常に動作するようです解決策だが、それは無限ループしたサービスの初期化部分を同期する

public class Program { 

private static boolean started; 
private static Throwable throwable; 

public static void main(String[] args) { 
    final Object startedSetterLock = new Object(); 

    Thread thread = new Thread() { 
     public void run() { 
      System.out.printf("trying to start...\n"); 

      boolean ok; 
      Throwable t = null; 
      try { 
       init(); 
       ok = true; 
      } catch(Exception e) { 
       ok = false; 
       t = e; 
      } 

      synchronized(startedSetterLock) { 
       started = ok; 
       throwable = t; 
       startedSetterLock.notifyAll(); 
      } 

      if(!ok) { 
       return; 
      } 

      while(true) { 
       try { 
        System.out.printf("working...\n"); 
        Thread.sleep(1000); 
       } catch(InterruptedException e) { 
        System.out.printf("interrupted\n"); 
       }     
      } 
     } 

     private void init() throws Exception { throw new Exception(); } // may throw 
    }; 

      // STARTER 
    synchronized(startedSetterLock) { 
     thread.start(); 
     try {   
      startedSetterLock.wait(); 
     } catch(InterruptedException e) { 
      System.out.printf("interrupted\n"); 
     } 
    }  

    // here I'm 100% sure that service has either started or failed to start 
    System.out.printf("service started: %b\n", started); 
    if(!started) { 
     throwable.printStackTrace(); 
    } 
} 
} 

:-)夫婦の時間が短く、それを作ることが可能だ場合、私は好奇心旺盛だとも、そのスレッド内で実行される初期化コードを持っている理由がありますだから、go()メソッドで明示的に初期化コードを実行し、すべてのものをスレッドに渡すようにアドバイスしないでください。

ありがとうございます!

答えて

2

Thread.start()メソッドのオーバーライドはどうですか?

public static void main(String[] args) { 
    Thread t = new Thread() { 
     public void run() { 
      while (true) { 
       try { 
        System.out.printf("working...\n"); 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        System.out.printf("interrupted\n"); 
       } 
      } 
     } 

     @Override 
     public synchronized void start() { 
      try { 
       init(); 
      } catch (Exception e) { 
       throw new RuntimeException(e); 
      } 
      super.start(); 
     } 

     private void init() throws Exception { 
      throw new Exception("test"); 
     } 
    }; 

    t.start(); 
} 
+1

Thread.start()は呼び出し元のスレッド内で実行されます。 – agibalov

+0

確かに。それから私はあなたが共通のロックを待たなければならないと思う。 – Vlad

関連する問題