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

2019-08-30 17:14:21 +08:00
 monetto

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>

}

2866 次点击
所在节点    Java
4 条回复
monetto
2019-08-30 17:14:32 +08:00
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
2019-08-30 17:15:29 +08:00
传入参数是 false 了,但是还是终止执行了。get 方法会报异常了。这是怎么回事??
求大神帮忙看看
chendy
2019-08-30 17:33:43 +08:00
复制粘贴运行
123
true
33
无异常
xzg
2019-08-30 17:58:07 +08:00
复制黏贴
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 状态已关闭抛出异常

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/596598

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX