多线程——interrupt(),interrupted()和isInterrupted()

停止线程是多线程中的一个技术点,Thread类的方法中,与停止线程有关的是: interrupt(),interrupted()和isInterrupted()
仅从名字上看就能感受到区分它们是有难度的T.T,还有一个stop()方法,该方法因”unsafe”而被标记为”Deprecated”,
本博客主要是对这三个方法区别的介绍,不会涉及到被弃用的方法,希望在正确有效的停止线程的路上有一点进步。

1. 函数定义

根据Java api,这三个方法的定义如下:

public void interrupt(): Interrupts this thread.
public static boolean interrupted(): Tests whether the current thread has been interrupted.
public boolean isInterrupted(): Tests whether this thread has been interrupted.

首先定义上,对这三个方法就有直观的认识,可以发现,最容易混淆的两个方法是:interrupted()和isInterrupted()

  • interrupted()是一个静态方法:检测当前线程是否已经中断;
  • isInterrupted():检测该线程是否已经中断。

也正如此,它们本质才是不同的,下面是根据Java api中对这三个方法的详细说明,对它们进行的详细解释。

2. interrupt()

尽管看上去是该方法是用于中断线程的,但是实质上,它的使用效果并不会停止一个正在运行的线程,
仅仅是在线程中打了一个停止的标记而已,需要加入一个判断才实现停止线程的功能。

关于如何停止线程,可以参考:多线程——停止线程

实例代码:

/*
 * 测试interrupt()方法
 */
public class Test_interrupt implements Runnable {

    @Override
    public void run() {
        for(int i=0; i<500000; i++){
            System.out.println("i=: "+i);
        }
    }

    public static void main(String[] args) {
        try {
            Test_interrupt r = new Test_interrupt();
            Thread t = new Thread(r,"test");
            t.start();
            Thread.sleep(1000);
            t.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }  
    }
}

运行结果:完成打印,线程并没有停止。

多线程——interrupt(),interrupted()和isInterrupted()_第1张图片

3. interrupted()

检测当前线程是否中断,如果当前线程处于中断状态,在首次调用该方法时会返回true,标识当前线程已经中断;
该方法具有在执行后清除状态标识的功能,即如果连续两次调用该方法,则第一次会返回true,第二次会返回false。

根据Java api,该方法的详细定义如下:

Tests whether the current thread has been interrupted.
The interrupted status of the thread is cleared by this method.
In other words, if this method were to be called twice in succession, the second call would return false (unless the current thread were interrupted again, after the first call had cleared its interrupted status and before the second call had examined it).

实例代码1:

/*
 * 测试interrupted()方法
 */
public class Test_interrupted implements Runnable {

    @Override
    public void run() {
        for(int i=0; i<500000; i++){
            System.out.println("i=: "+i);
        }
    }

    public static void main(String[] args) {

        Test_interrupted r = new Test_interrupted();
        Thread t = new Thread(r,"test");
        t.start();       
        t.interrupt();    //中断线程t, 测试Thread.interrupted()的返回值

        System.out.println("是否停止1?: "+Thread.interrupted());
        System.out.println("是否停止2?: "+Thread.interrupted());        
    }
}

运行结果1:

这里写图片描述

分析1:
本例通过设置t.interrupt();来测试Thread.interrupted(),连续两次调用该方法,返回结果都是false,
这表明当前线程从未中断过,原因是这个“当前线程”是线程main,即执行t.interrupt();的线程,而不是线程t

代码实例2:

/*
 * 测试interrupted()方法
 */
public class Test_interrupted implements Runnable {

    @Override
    public void run() {
        for(int i=0; i<500000; i++){
            System.out.println("i=: "+i);
        }
    }

    public static void main(String[] args) {

        Test_interrupted r = new Test_interrupted();
        Thread t = new Thread(r,"test");
        t.start();     
        Thread.currentThread().interrupt();    //中断当前线程, 测试Thread.interrupted()的返回值

        System.out.println("是否停止1?: "+Thread.interrupted());
        System.out.println("是否停止2?: "+Thread.interrupted());        
    }
}

运行结果2:

这里写图片描述

分析2:
本例通过设置Thread.currentThread().interrupt();来测试Thread.interrupted()
连续两次调用该方法,第一次的返回结果都是true,第二次的返回结果是false,这表明当前线程main中断过,
原因是Thread.interrupted()在第一次调用时捕捉到了中断标记,在第二次调用的时清除了该标记位。

4. isInterrupted()

检测该线程是否中断,线程的中断状态不会受到该方法的影响,即连续调用该方法,在执行后不会清除状态标识

根据Java api,该方法的详细定义如下:

Tests whether this thread has been interrupted.
The interrupted status of the thread is unaffected by this method.

代码实例:

/*
 * 测试interrupt()方法
 */
public class Test_interrupted implements Runnable {

    @Override
    public void run() {
        for(int i=0; i<500000; i++){
            System.out.println("i=: "+i);
        }
    }

    public static void main(String[] args) {

        Test_interrupted r = new Test_interrupted();
        Thread t = new Thread(r,"test");
        t.start();
        t.interrupt();    //中断线程t, 测试t.isInterrupted()的返回值

        System.out.println("是否停止1?: "+t.isInterrupted());
        System.out.println("是否停止2?: "+t.isInterrupted());
    }
}

运行结果:

这里写图片描述

分析:
本例通过设置t.interrupt();来测试t.isInterrupted(),连续两次调用该方法,返回结果都是true,
这表明该线程已中断,该线程t,且该方法不具有在执行后清除状态标识的功能,与方法描述一致。


其实我在总结之前仍然有些迷糊,本博客写完之后就清楚多了,所以动手写一写、做一些小实验总是好的~
参考书籍:《Java多线程编程技术》,感谢作者~

献上昨夜的月食,很美~

多线程——interrupt(),interrupted()和isInterrupted()_第2张图片

你可能感兴趣的:(多线程)