我正在尝试实现一段代码来同步启动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()
方法中明确地运行初始化代码,然后只传递所有东西到线程。
谢谢!
答案 0 :(得分: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();
}