java中取消异常提醒_java – 如何从提交给执行程序的已取消的中断调用中获取异常?...

您可以使用自定义的FutureTask来帮助自己:

public class TracingFutureTask extends FutureTask {

private Throwable trace;

private boolean done;

public TracingFutureTask(Callable callable) {

super(callable);

}

public TracingFutureTask(Runnable runnable, T result) {

super(runnable, result);

}

@Override

public void run() {

try { super.run(); }

finally { synchronized(this) { done=true; notifyAll(); }}

}

@Override

protected void setException(Throwable t) {

trace=t;

super.setException(t);

}

public synchronized Throwable getException() throws InterruptedException {

while(!done) wait();

return trace;

}

public synchronized Throwable getException(long timeout)

throws InterruptedException, TimeoutException {

for(long deadline = System.currentTimeMillis()+timeout, toWait=timeOut;

!done; toWait = deadline-System.currentTimeMillis()) {

if ( toWait <=0 ) throw new TimeoutException(

"Thread did not end in " + timeout + " milliseconds!" );

wait(toWait);

}

return trace;

}

public static TracingFutureTask submit(Executor e, Callable c) {

TracingFutureTask ft=new TracingFutureTask<>(c);

e.execute(ft);

return ft;

}

public static TracingFutureTask submit(Executor e, Runnable r, V v) {

TracingFutureTask ft=new TracingFutureTask<>(r, v);

e.execute(ft);

return ft;

}

}

这会跟踪基类的异常,但与基类不同,它甚至在作业被取消时也会记住它.这就是为什么run()方法和getException()之间存在额外的同步,就像在取消情况下作业可以在记录异常之前进入取消状态(这意味着“完成”),因此我们必须介绍我们自己的完成状态与适当的同步.

它可以像:

ExecutorService executor = Executors.newSingleThreadExecutor();

TracingFutureTask future=TracingFutureTask.submit(executor, new Callable(){

@Override

public synchronized String call() throws Exception {

this.wait( 60000 );

return "foo";

}

});

try {

future.get(500, TimeUnit.MILLISECONDS);

fail("Timeout expected.");

} catch (ExecutionException | TimeoutException e) {

e.printStackTrace();

}

if(future.cancel(true)) {

System.err.println("cancelled.");

Throwable t = future.getException();

if(t!=null) t.printStackTrace(System.err.append("cancellation caused "));

}

(从您的示例代码派生)

java.util.concurrent.TimeoutException

at java.util.concurrent.FutureTask.get(FutureTask.java:205)

at so.TestCancel.main(TestCancel.java:69)

cancelled.

cancellation caused java.lang.InterruptedException

at java.lang.Object.wait(Native Method)

at so.TestCancel$1.call(TestCancel.java:64)

at so.TestCancel$1.call(TestCancel.java:61)

at java.util.concurrent.FutureTask.run(FutureTask.java:266)

at so.TracingFutureTask.run(TestCancel.java:33)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

at java.lang.Thread.run(Thread.java:745)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值