V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
monetto
V2EX  ›  Java

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

  •  
  •   monetto · 2019-08-30 17:14:21 +08:00 · 2752 次点击
    这是一个创建于 1701 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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-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
        2
    monetto  
    OP
       2019-08-30 17:15:29 +08:00
    传入参数是 false 了,但是还是终止执行了。get 方法会报异常了。这是怎么回事??
    求大神帮忙看看
    chendy
        3
    chendy  
       2019-08-30 17:33:43 +08:00
    复制粘贴运行
    123
    true
    33
    无异常
    xzg
        4
    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 状态已关闭抛出异常
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2957 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 13:09 · PVG 21:09 · LAX 06:09 · JFK 09:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.