monetto
V2EX  ›  Java

FutureTask 的 cancel 方法为什么传参 false 依然会终止线程?

By monetto at 2019 年 8 月 30 日 · 3766 次点击

import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; import static java.lang.Thread.sleep;

public class MainClass { public static void main(String[] args) throws InterruptedException { FutureTask<integer> result = new FutureTask<integer>(new CallableThread()); Thread thread = new Thread(result); thread.start(); sleep(500); try { result.cancel(false); System.out.println(result.isCancelled()); sleep(2000); System.out.println("Get: " + result.get()); } catch (Exception e) {</integer></integer>

    }
}

}

class CallableThread implements Callable<integer> { public Integer call() throws Exception { System.out.println(123); sleep(2000); System.out.println(33); return 444; }</integer>

}

4 条回复  •  2019-08-30 17:58:07 +08:00
monetto
   1
monetto  
OP
   2019 年 8 月 30 日
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import static java.lang.Thread.sleep;

public class MainClass {
public static void main(String[] args) throws InterruptedException {
FutureTask<Integer> result = new FutureTask<Integer>(new CallableThread());
Thread thread = new Thread(result);
thread.start();
sleep(500);
try {
result.cancel(false);
System.out.println(result.isCancelled());
sleep(2000);
System.out.println("Get: " + result.get());
} catch (Exception e) {

}
}

}

class CallableThread implements Callable<Integer> {
public Integer call() throws Exception {
System.out.println(123);
sleep(2000);
System.out.println(33);
return 444;
}

}
monetto
   2
monetto  
OP
   2019 年 8 月 30 日
传入参数是 false 了,但是还是终止执行了。get 方法会报异常了。这是怎么回事??
求大神帮忙看看
chendy
   3
chendy  
   2019 年 8 月 30 日
复制粘贴运行
123
true
33
无异常
xzg
   4
xzg  
   2019 年 8 月 30 日
复制黏贴
123
true
33

Process finished with exit code 0
修改 catch 代码块抛出异常
} catch (Exception e) {
e.printStackTrace();
}
结果:
java.util.concurrent.CancellationException
at java.util.concurrent.FutureTask.report(FutureTask.java:121)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at cmdt.minibus.model.MainClass.main(MainClass.java:17)
--------------------
源码:
设置 cancel,state 修改

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;
}

result.get 源码:
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}

private V report(int s) throws ExecutionException {
Object x = outcome;
if (s == NORMAL)
return (V)x;
if (s >= CANCELLED)
throw new CancellationException();
throw new ExecutionException((Throwable)x);
}
-----------
这里 result.cancel(false); 将线程终止,修改任务状态 state,后来执行 result.get()根据 state 状态已关闭抛出异常
© 2026 V2EX · 50ms · 3.9.8.5