我有一个扩展Thread
的内部类private class TestStart extends Thread {
public void run() {
try {
startServer();
}
catch (Exception e) {
/// How to handle it?
}
}
}
主线程中的调用者:
public void start() throws Exception {
Thread st = new TestStart();
st.start();
}
方法startServer()通过其API抛出Exception,因此我必须使用try-catch,因为Thread.run()不会在方法定义中“抛出”异常。我需要将捕获的异常冒泡到主线程中来处理它。有一个简单的方法吗?感谢
答案 0 :(得分:3)
如果使用ExecutorService
而不是使用原始线程,则可以通知您未捕获的异常:
class MyCallable implements Callable<Void> {
@Override public Void call() throws Exception {
// Do something - you don't need to catch Exception as Callable throws it.
// ...
return null; // A return is necessary from a Callable.
}
}
在某处创建执行服务,例如:
ExecutorService executor = Executors.newFixedThreadPool(1);
然后,在启动线程的代码中:
Future<?> future = executor.submit(new MyCallable());
try {
future.get(); // Blocks until the Callable completes.
} catch (ExecutionException e) {
// You reach here if an exception is thrown in the Callable -
// The exception is accessible via e.getCause().
}
答案 1 :(得分:0)
在你的线程上设置一个新的异常处理程序。
st.setDefaultUncaughtExceptionHandler(new Thread.
UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t + " throws exception: " + e);
}
});
将该代码放在start()之前;
答案 2 :(得分:0)
有一些可能的解决方案。例如:
使用setUncaughtExceptionHandler()/ setDefaultUncaughtExceptionHandler()并更改你的try / catch
try {
startServer();
}
catch (RuntimeException e) {
throw e;
}
catch (Exception e) {
throw new RuntimeException(e);
}
或使用自定义侦听器
private class TestStart extends Thread {
private final ServerStateListener lnr;
TestStart(ServerStateListener lnr) {
this.lnr = lnr;
}
public void run() {
try {
startServer();
lnr.onServerStarted();
}
catch (Exception e) {
lnr.onServerStoppedByError(e);
}
}
}
或者只是保存Exception并在.join
之后阅读private class TestStart extends Thread {
private Exception error; // if you start and join and read this property within one thread, you don't need to use volatile, otherwise do it for safe publication
public void run() {
try {
startServer();
}
catch (Exception e) {
error = e;
}
}
public Exception getError() {
return error;
}
}
或者使用ExecutorService / Callable代替您自己的线程,正如Andy建议的那样。