Java 我必须在FutureTask中手动处理中断吗?
我目前正试图了解Java 我必须在FutureTask中手动处理中断吗?,java,interrupt,futuretask,Java,Interrupt,Futuretask,我目前正试图了解FutureTask.cancel(true)是如何工作的,这是相关的官方文件 如果任务已经启动,则MayInterruptFrunning参数确定执行此任务的线程是否应该中断以尝试停止任务 这是从Github获得的cancel的实现 public boolean cancel(boolean mayInterruptIfRunning) { if (!(state == NEW && UNSAFE.compareAndSwapInt(
FutureTask.cancel(true)
是如何工作的,这是相关的官方文件
如果任务已经启动,则MayInterruptFrunning参数确定执行此任务的线程是否应该中断以尝试停止任务
这是从Github获得的cancel
的实现
public boolean cancel(boolean mayInterruptIfRunning) {
if (!(state == NEW &&
UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
return false;
try { // in case call to interrupt throws exception
if (mayInterruptIfRunning) {
try {
Thread t = runner;
if (t != null)
t.interrupt();
} finally { // final state
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
}
}
} finally {
finishCompletion();
}
return true;
}
因此,基本上我们可以看到,cancel(true)
所做的唯一事情就是在工作线程上调用interrupt
。那么,如果我的FutureTask
的call
方法看起来像这样呢
SomeType call() {
for(int i = 0; i < 1000000000; i++) {
//pass
}
return someValue;
}
SomeType调用(){
对于(int i=0;i<100000000;i++){
//通过
}
返回一些值;
}
那么,我的问题是,我是否必须添加线程中断的手动检查才能取消此类未来任务?我的意思是这似乎很明显,因为我没有调用任何IO函数来处理中断,也没有检查
线程。currentThread().isInterrupted()
,所以这个任务似乎是不可取消的,但是,在任何官方文档中都没有提到,我们必须处理中断或self才能取消任务,因此最好征求其他人的意见。是的,您必须处理CancellationException(此异常抛出FutureTask.get()方法),如果不这样做,此异常将被抛出到JVM。查看本例,它将输出“任务已取消”:
公共类MainTest{
公共静态void main(字符串…参数){
FutureTask FutureTask=新的FutureTask(new MyCallable());
ExecutorService ExecutorService=Executors.newFixedThreadPool(1);
executorService.submit(未来任务);
试一试{
futureTask.cancel(true);
System.out.println(futureTask.get());
}捕获(取消异常e){
System.out.println(“任务被取消”);
}捕获(中断异常|执行异常e){
System.out.println(“出了点问题!”);
}
executorService.shutdown();
}
}
类MyCallable实现了Callable{
@凌驾
公共长途电话(){
对于(int i=0;i<100000000;i++){
//通过
}
返回1L;
}
}
Java中没有先发制人的功能。任何东西要想被打断,它必须配合。因此,是的,任务必须检查它是否被中断,否则即使未来被取消,它仍将运行到最后。令人失望,我知道。谢谢你的回答,但实际上这与问题无关。在您的示例中,您从未开始执行MyCallable
,因此在实际启动之前将其取消。所以,在您的示例中,传递true
或false
以取消并不重要,因为任务从未执行过。我的问题是取消已经在进行的任务,直接在call
中处理中断。哦,是的,我忘了启动任务。对不起,我理解错了这个问题,我不知道如何在call方法中处理这个问题。。。