`TimeoutException`和`CancellationException`之间的区别

时间:2016-12-19 22:56:06

标签: java multithreading executorservice

根据Javadoc,Future.get(), 引发TimeoutExceptionCancellationException以及其他2人。

CancellationExceptionTimeoutException之间有什么区别?

据我所知,当线程超时并因此执行程序取消它时,抛出Future.cancel()。但是当CancellationException被抛出的时候呢? 是否存在定时线程超时且未取消的情况?

看到CancellationException when using ExecutorServiceWhat is the best way to handle an ExecutionException?加上其他人。

TIA。

// ---------------

更新

除非开发人员明确地做了,否则

会不会打电话给Future.cancel()

javadoc未提及由此引起的Future.cancel()的任何内容。

我有一个代码进入系统,我可能因为一定的时间限制而取消该代码。但是,我必须能够告诉Future.isDone()何时返回true,它是这样做的,因为任务已完成或被取消。 从它看来,{{1}}在这两种情况下都返回true。 {{1}}或其他任何方法都无济于事。

3 个答案:

答案 0 :(得分:3)

  

据我所知,当线程超时并因此执行者取消它时,抛出CancellationException

没有。如果在任务完成之前调用CancellationException的{​​{1}}方法,则会引发Future,并随后调用其cancel()方法之一。

  

但是什么时候抛出TimeoutException?

如果在没有完成任务的情况下经过指定的时间,<get()TimeoutException)将被CancellationException抛出。

  

是否存在定时线程超时且未取消的情况?

是。时间安排与取消时完全不同。

关于更新:

  除非开发人员明确地做了,否则

会不会打电话给Future.get(long, Timeunit)

只有对相关特定Future.cancel()有引用的人才能调用其Future方法。 cancel()不会调用它,如果这是你的意思,特别是,超时与取消不同,因此不会导致ExecutorService

  

javadoc没有提及由此引起的CancellationException的任何内容。

CancellationException 的Javadoc没有提到它,我也没有看到它的特殊需要。 The exception's own class-level javadocs解释了它的重要性,Future.cancel()的那些方法的javadocs可以把它归结为它们所做的文件。

  

我有一个代码进入系统,我可能因为一定的时间限制而取消该代码。

所以听起来你会调用Future的两个arg版本来指定时间限制,然后在超时的情况下(由Future.get()发出信号)你会调用TimeoutException

  

然后,我必须能够告诉Future.cancel()何时返回Future.cancel(),这样做是因为任务已完成或已被取消。从它看来,true在这两种情况下都会返回true。

你从哪里得到的?您自己引用的Future.cancel()文档说明该方法返回

  

Future.cancel()如果任务无法取消,通常是因为它已经正常完成; false否则

因此,如果true返回Future.cancel(),那么您可以确信最终结果由true表示的任务已成功取消,因为任何结果都不会生成,并且其后一个Future方法的调用将抛出get()。如果还没有开始那么它永远不会;如果它已经启动,那么它就被打断了。

后一种选择需要将CancellationException传递给true,在这种情况下,实际停止的任务取决于其实现对其线程的响应被中断。目前尚不清楚,如果任务实际上没有停止运行,是否认为正在进行的任务的取消是成功的;事实上,这可能与实现有关。

答案 1 :(得分:1)

取消任务时,通过调用cancel()来抛出CancellationException。

当您要求get()等待给定时间的结果时,抛出TimeoutException,结果需要的时间超过生成时间。

线程没有超时。并且执行者不会取消线程。

答案 2 :(得分:0)

  

据我所知,当线程超时并因此执行者取消它时,抛出CancellationException

不,不完全。如果线程A正在调用future.get()而另一个线程B调用future.cancel(),那么future.get()会为线程A抛出CancellationException。例外是试图告诉线程A该作业是什么等待被取消了。

  

但是什么时候抛出TimeoutException?是否存在定时线程超时且未取消的情况?

没有。如果线程A调用future.get(long, TimeUnit),则该方法在指定的超时到期时抛出TimeoutException意味着正在运行的作业超时只是等待作业完成超时的线程A.未来很可能仍在继续。

  

除非开发人员明确指出,否则其他人会调用Future.cancel()吗?

这是非常依赖情况的。除了启动作业的线程之外的其他人调用future.cancel(...)但是肯定不是闻所未闻的,这有点不寻常。

  

我有一个代码进入系统,我可能因为一定的时间限制而取消该代码。但是,我必须能够告诉Future.cancel()何时返回true,它是这样做的,因为任务已完成或被取消。

如果作业被取消,

future.cancel(...)将返回true。引用javadocs:

  

返回:如果无法取消任务,则返回false,通常是因为它已经正常完成;否则

因此,如果它返回true,则成功取消作业。您可以通过之后调用future.get()来确保应该抛出CancellationException

如果线程已经在运行,则无法轻松取消也非常重要。即使你调用future.cancel(true),这也只会中断不会立即停止它的线程。它会导致Thread.sleep(...)和抛出InterruptedException的其他方法抛出,但通常你必须编写代码来遵守中断标志。类似的东西:

// keep running until we are interrupted
while (!Thread.currentThread.isInterrupted()) {
    ...
}