Thread中断简单介绍

Android  Java  2024年8月1日 pm6:45发布4个月前更新 城堡大人
131 0 0

前言

简答记录一下Thread中断相关的内容。

记录一下,方便自己查阅。

正文

Thread中断主要涉及如下几个方法:

  1. interrupt()

  2. isInterrupted()

  3. interrupted()

下面单独介绍一下。

interrupt()

interrupt()使线程中断。

重点:当线程调用interrupt()时,仅仅设置中断标志位true,此时线程是不会被中断的,会一直执行直到结束。

为了让人易懂,简单测试一下。

测试一

先定义一个MyThread类(比较简单,只是为了测试而已)

private class MyThread extends Thread {
    public MyThread(String name) {
        setName(name);
    }

    @Override
    public void run() {
        super.run();
        Log.d(TAG, "run thread name : " + getName() + " start ");
        for (int i = 0; i < 1000; i++) {
            Log.d(TAG, "run thread name : " + getName() + " [ " + i + " ] ");
        }
        Log.d(TAG, "run thread name : " + getName() + " end , isInterrupted() : " + isInterrupted());
    }
}
MyThread myThreadA = new MyThread("Thread_A");
myThreadA.start();
try {
    Thread.sleep(10);
} catch (InterruptedException e) {
    throw new RuntimeException(e);
}
Log.d(TAG, "myThreadA.interrupt() : ");
myThreadA.interrupt();

下面打印日志:

// ...为省略,打印太多了。
run thread name : Thread_A start
...
run thread name : Thread_A [ 102 ]
...
myThreadA.interrupt() 
...
run thread name : Thread_A [ 999 ] 
run thread name : Thread_A end , isInterrupted() : true

从上面可以看出,调用interrupt()后,并不会终止线程中断,直到线程for循环结束,最后打印时中断标志位以为true。

  1. interrupt()会改变中断标志位位true

  2. interrupt()不会打断Thread执行任务,直到自动结束。

测试二

当然,如果线程调用了wait方法、join方法或者sleep方法而被阻塞挂起,此时如果线程A的interrupt(),线程会在调用这些方法的地方抛出InterruptedException异常而返回。

下面我们在ThreadA中的for循环中添加sleep(),其他的保持不变。

private class MyThread extends Thread {
    public MyThread(String name) {
        setName(name);
    }

    @Override
    public void run() {
        super.run();
        Log.d(TAG, "run thread name : " + getName() + " start ");
        for (int i = 0; i < 1000; i++) {
            Log.d(TAG, "run thread name : " + getName() + " [ " + i + " ] ");
            try {
                sleep(10);
            } catch (InterruptedException e) {
                Log.d(TAG, "run e: "+ e);
                break;//退出for循环
            }
        }
        Log.d(TAG, "run thread name : " + getName() + " end , isInterrupted() : " + isInterrupted());
    }
}

调用那部分不改变,这里省略,打印日志如下:

run thread name : Thread_A start 
run thread name : Thread_A [ 0 ] 
myThreadA.interrupt() 
run e: java.lang.InterruptedException
run thread name : Thread_A end , isInterrupted() : false

很快就在sleep()中收到InterruptedException,然后我们退出了for循环。

  1. interrupt() 时,如果有sleep()等代码,会抛出InterruptedException

  2. 在1(基础上)抛出异常后最后中断状态为false

也就是说出行InterruptedException后,会影响中断标志位。

由于对Thread源码不是很了解,在,有兴趣的可以看Thread相关的源码。

后续后续有空看一下,这里先插个眼!

isInterrupted()

检测当前线程是否被中断,如果是返回true,否则返回false。

下面测试一下,在ThreadA中新增isInterrupted()判断,如果为true,就结束for循环

private class MyThread extends Thread {
    public MyThread(String name) {
        setName(name);
    }

    @Override
    public void run() {
        super.run();
        Log.d(TAG, "run thread name : " + getName() + " start ");
        for (int i = 0; i < 1000; i++) {
            Log.d(TAG, "run thread name : " + getName() + " [ " + i + " ] ");
            if(isInterrupted()){
                Log.d(TAG, "run isInterrupted break: ");
                break;
            }
        }
        Log.d(TAG, "run thread name : " + getName() + " end , isInterrupted() : " + isInterrupted());
    }
}

其他的保持不变[跟interrupt()中代码一样,这里略],打印日志如下:

run thread name : Thread_A start 
run thread name : Thread_A [ 0 ] 
...
myThreadA.interrupt() : 
run thread name : Thread_A [ 100 ] 
run thread name : Thread_A [ 101 ] 
run isInterrupted break: 
run thread name : Thread_A end , isInterrupted() : true

执行中断后,isInterrupted()返回true,然后break退出循环。

  1. interrupt()时,isInterrupted()会返回true

  2. isInterrupted()返回结果后,不会改变中断标志,所以打印依旧为true

interrupted()

如果线程被中断,返回true,否则返回false。

如果interrupted()返回true后,会把中断标志位清除,置为false。

下面简单的测试一下。新增interrupted()判断,如果返回true,就break线程中的for选好

private class MyThread extends Thread {
    public MyThread(String name) {
        setName(name);
    }

    @Override
    public void run() {
        super.run();
        Log.d(TAG, "run thread name : " + getName() + " start ");
        for (int i = 0; i < 1000; i++) {
            Log.d(TAG, "run thread name : " + getName() + " [ " + i + " ] ");
            if(interrupted()){
                Log.d(TAG, "run interrupted break : ");
                break;
            }
        }
        Log.d(TAG, "run thread name : " + getName() + " end , isInterrupted() : " + isInterrupted());
    }
}

执行后日志打印。

run thread name : Thread_A start 
run thread name : Thread_A [ 0 ] 
...
myThreadA.interrupt() : 
run thread name : Thread_A [ 242 ] 
run interrupted break : 
run thread name : Thread_A end , isInterrupted() : false
  1. 调用interrupt()后,interrupted()返回true

  2. interrupted()执行后,把中断标志位置为false

小结

  1. interrupt()设置中断标志位,如果有sleep(),wait()等会抛出InterruptedException

  2. isInterrupted()判断中断标志位是否为true

  3. interrupted()判断中断标志位是否为true,如果当为true,把中断标志位清除(置为false)

  4. interrupted()是静态方法

至于深入Thread源码,暂时没空,先插个眼

参考文章

  1. 《Java并发编程之美》

 历史上的今天

  1. 2023: ViewPager禁止左右滚动(0条评论)
  2. 2022: Android GridView horizontalSpacing属性值无效(0条评论)
  3. 2021: 陈先发:前世(0条评论)
  4. 2019: 朱光潜:有趣的灵魂都有静气(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

Android Zygote进程的启动流程简单分析

前言在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的,因为Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程for...

AIDL使用异常记录

前言记录一下AIDL中常见的问题,方便自己回忆和学习。正文这里以BookBean为例package com.biumall.binderlibmedia.bean;import android.os.Parcel;import android.os.Parcelable;public...

常见的文件头或文件尾十六进制表示

前言最近在加载图片时,由于需要对不同图片使用不同的加载方式,因此需要通过判断图片的类型进行条用不同的接口。因此摘抄于此,以便查阅。正文下面的文件头或文件尾都是用十六进制表示的。JPEG (jpg)文件头:FFD8FF文件尾:FFD9PNG (png)文件头:89504E47文件尾...

史铁生:我与地坛[节选]

现在让我想想,十五年中坚持到这园子来的人都是谁呢?好像只剩了我和一对老人。十五年前,这对老人还只能算是中年夫妇,我则货真价实还是个青年。他们总是在薄暮时分来园中散步,我不大弄得清他们是从哪边的园门进来,一般来说他们是逆时针绕这园子走。男人个子很高,肩宽腿长,走起路来目不斜视,胯以上直至脖颈挺直不...

冰心:我们把春天吵醒了

季候上的春天,像一个困倦的孩子,在冬天温暖轻软的绒被下,安稳地合目睡眠。但是,向大自然索取财富、分秒必争的中国人民,是不肯让它多睡懒觉的!六亿五千万人商量好了,用各种洪大的声音和震天撼地的动作来把它吵醒。大雪纷飞。砭骨的朔风,扬起大地上尖刀般的沙土……我们心里带着永在的春天,成群结队地...

村田浩一:假想游戏

一个年轻男子在楼梯上超过一个中年男子,奔上了月台,想跳进最近的门,但只差了一步没赶上,门已关上,火车无情地开动了。年轻男子呼吸急促,很遗憾地咂了一下嘴。“哎呀,可惜了。”中年男子这么说着靠过来。他戴副眼镜,稍胖,看起来为人厚道。年轻男子点一下头坐在长椅上。“对,差一步。火车应该稍等一下。”...