future task cancel

1 FutureTask.cancel 干了啥
    //有一个入参,需要说明task是否是可中断的
    public boolean cancel(boolean mayInterruptIfRunning) {
        if (state != NEW)
            return false;
        if (mayInterruptIfRunning) {
            //尝试修改futuretask的运行状态
            if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING))
                return false;
            //获取当前线程发出中断信号
            Thread t = runner;
            if (t != null)
                t.interrupt();
            //修改task装态为已中断的
            UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state
        }
        //如果是不可中断的只修改task的状态为cancelled
        else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED))
            return false;
        //执行finishCompletion方法
        /**
         * Removes and signals all waiting threads, invokes done(),and nulls out callable.
         */
        finishCompletion();
        return true;
    }

 

跑完了 返回false

没跑完,输入true,修改为Interrupting,中断t,修改为Interrupted,返回true

没跑完,输入false,修改为Cancelled,返回true

 

compareAndSwapInt 相等并赋值成功返回true,否则返回false

 

 

 

2 FutureTask.cancel与Thread.interrupt区别

package multithreadci;

import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * Created by mac on 2023/9/4.
 */
public class TestCancel {

    public static void main(String []f ) {

        FutureTask subTask = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception {
                Thread.sleep(100000);
                return true;
            }
        });

        Thread threadSubTask = new Thread(subTask);
        threadSubTask.start();

        FutureTask parentTask = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception {
                try {
                    Object res = subTask.get();
                    System.out.print(res);
                } catch (InterruptedException e) {
                    e.printStackTrace();            // 2
                } catch (ExecutionException e) {
                    e.printStackTrace();            // 3
                } catch (CancellationException e) {
                    e.printStackTrace();            // 1
//                }
//
//                try {
//                    subTask.get();
//                } catch (Exception e) {
//                    e.printStackTrace();
                }
                return true;
            }
        });

        Thread threadParentTask = new Thread(parentTask);
        threadParentTask.start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                /**
                 * 有对.get所在线程inturrupt之后,总是抛Interrupted而不是Cancellation
                 * 因为get中part唤醒后第一个就是判断是否被中断,根本走不到return和后面的report Cancellatioln
                 * 如果出现Cancellation,一定没有对.get所在线程interrupt或所在future cancel
                 */

                int cc = 5;
                switch (cc) {
                    // 仅对subtask的thread interrupt
                    case 1:     // 进3
                        threadSubTask.interrupt();
                        break;
                    // 仅对subtask cancel,不涉及对parent thread的interrupt
                    case 2:     // 进1
                        subTask.cancel(true);
                        break;
                    // 涉及对parent thread的interrupt
                    case 3:     // 进1
                        subTask.cancel(true);
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        parentTask.cancel(true);
                        break;
                    case 4:     // 进2
                        subTask.cancel(true);
                        parentTask.cancel(true);
                        break;
                    case 5:     // 进2
                        parentTask.cancel(true);
                        subTask.cancel(true);
                        break;
                }
            }
        }).start();


    }
}

 

3

package com.jds.test.httpproxy;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class TestCancel {

    public static void main(String []f){

        FutureTask childTask = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception {
                Thread.sleep(100000);
                return true;
            }
        });
        Thread threadSubTask = new Thread(childTask, "mock child task");
        threadSubTask.start();

        FutureTask parentTask = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception {
                try {
                    Object res = childTask.get();
                    System.out.print(res);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
//                } catch (CancellationException e) {
//                    e.printStackTrace();
//                    Thread.currentThread().interrupt();
                }  catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                if(Thread.currentThread().isInterrupted()) {
                    System.out.println("quit");
                } else {
                    System.out.println("I'm still running, hahaha, come to stop me");
                }
                return true;
            }
        });
        Thread threadParentTask = new Thread(parentTask, "mock parent task");
        threadParentTask.start();

        Timer timer = new Timer("mock ecore's cancelling task action");
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                childTask.cancel(true);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {

                }
                parentTask.cancel(true);
            }
        }, 5000);
    }
}

  

 

java.util.concurrent.CancellationException
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:121)
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
at com.jds.test.httpproxy.TestCancel$2.call(TestCancel.java:28)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.lang.Thread.run(Thread.java:834)
I'm still running, hahaha, come to stop me

posted on 2023-09-04 20:33  silyvin  阅读(10)  评论(0编辑  收藏  举报