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()
メソッドで明示的に初期化コードを実行し、すべてのものをスレッドに渡すようにアドバイスしないでください。
ありがとうございます!
Thread.start()は呼び出し元のスレッド内で実行されます。 – agibalov
確かに。それから私はあなたが共通のロックを待たなければならないと思う。 – Vlad