Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从Runnable重新刷新已检查的异常_Java_Multithreading_Exception_Runnable - Fatal编程技术网

Java 从Runnable重新刷新已检查的异常

Java 从Runnable重新刷新已检查的异常,java,multithreading,exception,runnable,Java,Multithreading,Exception,Runnable,我从主类执行多个任务: ExecutorService executor = Executors.newFixedThreadPool(N); for (int i = 0; i < M; i++) { executor.execute(task); } executor .shutdown(); while (!executor.isTerminated()){} //block ExecutorService e

我从主类执行多个任务:

ExecutorService executor = Executors.newFixedThreadPool(N);
    for (int i = 0; i < M; i++) {
    executor.execute(task);
}

executor .shutdown(); 
while (!executor.isTerminated()){} //block                          
ExecutorService executor=Executors.newFixedThreadPool(N);
for(int i=0;i
task是一个类,
实现可运行的

run()
方法中,我调用了一些带有选中异常的api,这意味着我需要用try-catch块来包围调用。
所以,我的主类无法知道抛出了异常


我怎样才能解决这个问题

始终重新显示异常,让调用方知道它,否则异常可能会转义。您可以在《实践中的Java并发》一书中找到很好的解释。对不起,我应该把它作为你的评论,但是我的分数不允许我:)

你可以创建一个主异常。假设您已经创建了自己的
UncheckedException
类,该类扩展了
RuntimeException
,定义了所有必需的构造函数。你可以说,

    @Override
    public void run() {
        try {
            //some code that throws checked exception
        }
        catch(Exception e) {
            throw new UncheckedException(e);
        }
    }

此代码将编译,因为此处不需要
抛出
声明

您可以使用可调用的:

Callable<?> task = new Callable<Void> () {
    public Void call() throws Exception {
        someCodeThatThrowsCheckedExceptions();
        return null;
    }
}
Callable task=new Callable(){
public Void call()引发异常{
通过CheckedExceptions()的某些代码;
返回null;
}
}
然后:

Future f=executor.submit(任务);
试一试{
f、 get();
}捕获(执行例外){
System.out.println(“任务引发异常:+e.getCause().getMessage());
}

如果您可以修改任务以实现
可调用
,那么您可以从call()抛出选中的异常 由于任务不返回值,请使用
Callable


在我看来,一个好看的解决方案是实现而不是
Runnable
。两个主要区别是,
Callable
可以抛出已检查的异常,并且可能返回一个值。通过实现
Callable
,可以克服返回值的问题

您需要做的是:

  • 让您的任务实现
    Callable
    而不是
    Runnable
    ——将
    void run()
    更改为
    void call()抛出异常。无需尝试/捕获已检查的异常。添加
    返回null语句
    
  • 使用
    Future checkableResult=ExecutorService.submit(可调用)
  • 您可以通过调用
    checkableResult.get()
    ,检查它是否引发了异常,如果它引发了异常,则会引发异常。可以通过检索原始异常。特别要注意的是,
    get()
    是阻塞的-因此定期检查
    Callable.isDone()
    可能是您想要的(否则您最好在同一线程中运行它)

  • 另一种选择是将功能构建到
    Runnable
    volatile boolean isDone
    volatile Exception Exception
    )-但是为什么要重新发明轮子呢?

    您不能从Runnable重新生成异常。@yuris:是的,您可以:将它们包装到某个RuntimeException中。您的任务是否返回任何值?否,一无所获。
    Future<?> f = executor.submit(task);
    try {
        f.get();
    } catch (ExecutionException e) {
        System.out.println("task threw exception: " + e.getCause().getMessage());
    }
    
    class Task implements Callable<Void> {
        public Void call throws YourAPIException {
            //code that throws a checked exception
            return null;
        }
    }
    
    V call() throws Exception