Я пытаюсь реализовать фрагмент кода для синхронного запуска зацикленного сервиса в Java. Идея состоит в том, что код под комментарием // STARTER
следует рассматривать как часть метода Service.go()
, поэтому, если служба не запускается, я хочу синхронно перезапустить исключение. Этот фрагмент кода должен завершиться только в том случае, если я попытался запустить поток, дождался, пока поток выполнения не достигнет какой-то точки, а затем, если проблем нет, мой метод go()
завершается и поток завершается или, если возникли проблемы, я могу повторно выдать исключение, пойманное в методе run()
потока, из моего метода go (). Вот решение, которое, кажется, работает нормально, но мне интересно, можно ли сделать его в пару раз короче: -)
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()
, а затем просто передавать все вещи в нить.
Спасибо!