美文网首页并发编程
FutureTask的cancel方法真的能终止正在运行的线程吗

FutureTask的cancel方法真的能终止正在运行的线程吗

作者: 小胖学编程 | 来源:发表于2019-08-26 11:07 被阅读0次
Future的API

【疑问】

Future有一个cancel(mayInterruptIfRunning)方法。若任务正在执行,并且mayInterruptIfRunning设置为true,那么可以取消掉正在运行的线程吗?

【源码】

java.util.concurrent.FutureTask#cancel

1. 线程的声明周期变量

    /*
     * Possible state transitions:
     * NEW -> COMPLETING -> NORMAL
     * NEW -> COMPLETING -> EXCEPTIONAL
     * NEW -> CANCELLED
     * NEW -> INTERRUPTING -> INTERRUPTED
     */
    private volatile int state;
    private static final int NEW          = 0;
    private static final int COMPLETING   = 1;
    private static final int NORMAL       = 2;
    private static final int EXCEPTIONAL  = 3;
    private static final int CANCELLED    = 4;
    private static final int INTERRUPTING = 5;
    private static final int INTERRUPTED  = 6;

NEW:未运行状态,但是线程可能处于sleep,join,wait或未触发状态。

2. 线程的中断方法

   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
                    Thread t = runner;
                    if (t != null)
                        t.interrupt();
                } finally { // final state
                    UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
                }
            }
        } finally {
            finishCompletion();
        }
        return true;
    }
  1. 若线程不是NEW状态,那么cancel方法返回false,即不能取消该线程的运行。
  2. 若是NEW状态(即sleep,wait,join等状态时),本质上是调用了Thread的interrupt()方法,进行中断的。

java中结束线程的方法总结

其实在java中没有真正可以中断线程调用的方法。

  1. 早期的stop方法因为过于暴力的中断线程,可能带来不可预知的异常,不推荐使用。
  2. interrupt方法也需要线程代码片段中有sleep,wait,join这些方法的调用,否则不能停止线程。
  3. 在线程的while循环中加入一个标志位来控制退出。(volatile修饰的变量,但是不推荐)。
  4. 调用thread的isInterrupted()方法判断。这样外界可以调用线程的 thread.interrupt();方法来控制线程的结束。

推荐阅读

  1. 源码导读-帮助篇-什么叫做CAS算法【图文版】
  2. 小小建议——多线程与并发(1)线程的创建和使用
 UNSAFE.compareAndSwapInt(this, valueOffset, expect,update)

CAS的比较算法,原理就是通过比较预期值expect和主存中的valueOffset是否相等,若不相等返回false,若相等,则使用update更新主存中的valueOffset值。

UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);

将INTERRUPTED刷新到主存中。

相关文章

  • FutureTask的cancel方法真的能终止正在运行的线程吗

    【疑问】 Future有一个cancel(mayInterruptIfRunning)方法。若任务正在执行,并且m...

  • FutureTask demo

    将callable 封装到FutureTask 将futureTask submit 到线程池,并测试cancel...

  • Java 停止线程

    1概述 在Java中有以下3种方法可以终止正在运行的线程: 1)当run方法完成后线程终止。 2)使用stop方法...

  • 线程的停止

    在Java中有以下3中方法可以终止正在运行的线程: 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止...

  • 线程取消原理

    线程怎么取消 FutureTask 支持中断cancel(true)这时候直接往线程发中断标志。 不支持中断can...

  • 面试阿里,字节跳动,腾讯90%都会被问到如何终止线程?有几种方式

    在 Java 中有以下 3 种方法可以终止正在运行的线程: 使用退出标志,使线程正常退出,也就是当 run() 方...

  • Java多线程编程核心技术

    第1章 Java多线程技能 在Java中有以下3种方法可以终止正在运行的线程:1)使用退出标志,使线程正常退出,也...

  • 线程的停止和暂停

    在Java中有以下3种方法可以终止正在运行的线程 1.使用退出标志,也就是等待Run方法运行结束 2.使用stop...

  • 线程取消(pthread_cancel)

    基本概念 pthread_cancel调用并不等待线程终止,它只提出请求。线程在取消请求(pthread_canc...

  • 多线程(三)

    线程终止 1.run方法正常退出,线程自然终止2.因为一个没有捕获的异常终止了run方法,线程意外终止 线程中断 ...

网友评论

    本文标题:FutureTask的cancel方法真的能终止正在运行的线程吗

    本文链接:https://www.haomeiwen.com/subject/cqqrectx.html