有什么建议吗?我需要针对Java 5,但也很想知道在更新版本的Java中是否有更好的解决方案。
public static byte[] doSomethingWithTimeout( int timeout ) throws ProcessExecutionException, InterruptedException, IOException, TimeoutException {
Callable<byte[]> callable = new Callable<byte[]>() {
public byte[] call() throws IOException, InterruptedException, ProcessExecutionException {
//Do some work that could throw one of these exceptions
return null;
}
};
try {
ExecutorService service = Executors.newSingleThreadExecutor();
try {
Future<byte[]> future = service.submit( callable );
return future.get( timeout, TimeUnit.MILLISECONDS );
} finally {
service.shutdown();
}
} catch( Throwable t ) { //Exception handling of nested exceptions is painfully clumsy in Java
if( t instanceof ExecutionException ) {
t = t.getCause();
}
if( t instanceof ProcessExecutionException ) {
throw (ProcessExecutionException)t;
} else if( t instanceof InterruptedException ) {
throw (InterruptedException)t;
} else if( t instanceof IOException ) {
throw (IOException)t;
} else if( t instanceof TimeoutException ) {
throw (TimeoutException)t;
} else if( t instanceof Error ) {
throw (Error)t;
} else if( t instanceof RuntimeException) {
throw (RuntimeException)t;
} else {
throw new RuntimeException( t );
}
}
}
=== 更新 ===
许多人建议重新抛出通用异常或未经检查的异常,但我不想这样做,因为这些异常类型(ProcessExecutionException、InterruptedException、IOException、TimeoutException)非常重要——它们将被调用进程以不同的方式处理。如果我不需要超时功能,那么我希望我的方法抛出这4种特定的异常类型(除了TimeoutException)。我认为添加超时功能不应该改变我的方法签名以抛出通用异常类型。
throws Exception
并使用同一行代码抛出所有异常。您可以捕获ExecutionException
,然后只需throw e.getCause
-- 不要捕获其他任何异常,让它们自行传播。 - Marko Topolnik