我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:金算盘心水论坛 > 抛出异常 >

使用 FutureTask 的正确姿势

归档日期:05-16       文本归类:抛出异常      文章编辑:爱尚语录

  线程池的实现核心之一是FutureTask。在提交任务时,用户实现的Callable实例task会被包装为FutureTask实例ftask;提交后任务异步执行,无需用户关心;当用户需要时,再调用FutureTask#get()获取结果——或异常。

  随之而来的问题是,如何优雅的获取ftask的结果并处理异常?本文讨论使用FutureTask的正确姿势。

  如果没有抛出异常在,则outcome记录正常结果;如果抛出了异常,则outcome记录异常。

  如果认为正常结果和异常都属于“任务的输出”,则使用相同的变量outcome记录是合理的;同时,使用不同的结束状态区分outcome中记录的内容。

  FutureTask将用户实现的task封装为ftask,使用状态机和outcome管理ftask的执行过程。这些过程对用户是不可见的,直到用户调用get()方法。

  顺道明白了Callable实例是如何执行的,为什么实现Callable#call()方法时可以将受检异常抛到外层(而Runable#run()方法则必须在方法内处理,不能抛出)。

  5行利用定义状态的实际值判断ftask是否已完成,如果未完成(NEW、COMPLETING),则wait阻塞直到完成,该过程可抛出InterruptedException退出。

  如果结束状态为NORMAL,则outcome保存了正常结果,泛型强转,返回。

  如果不是被取消的,就是执行过程中task自己抛出了异常,则outcome保存了该异常t,包装返回ExecutionException。

  将异常t作为ExecutionException的cause包装起来,异常阅读方法参考你真的会阅读Java的异常信息吗。

  CancellationException是非受检异常,原则上可以不处理,但仍然建议处理。

  CancellationException异常中不会给出取消原因,包括是否因为被中断。

  猴子喜欢在一些语义模糊的地方加assert或抛出UnknownException代替注释。

  对InterruptedException的处理暂时不讨论(少有的用于控制流程的异常,猴子理解的有点模糊),读者可参考处理 InterruptedException。

本文链接:http://izytravel.com/paochuyichang/40.html