一文搞懂java线程中断

     2022-03-30     235

关键词:

下面的这断代码大家应该再熟悉不过了,线程休眠需要捕获或者抛出线程中断异常,也就是你在睡觉的时候突然有个人冲进来把你吵醒了。

try {
    Thread.sleep(3000);
} catch (InterruptedException e) {
    e.printStackTrace();
}

此时线程被打断后,代码会继续运行或者抛出异常结束运行,这并不是我们需要的中断线程的作用。

到底是什么是线程中断?

线程中断即线程运行过程中被其他线程给打断了,它与 stop 最大的区别是:stop 是由系统强制终止线程,而线程中断则是给目标线程发送一个中断信号,如果目标线程没有接收线程中断的信号并结束线程,线程则不会终止,具体是否退出或者执行其他逻辑由目标线程决定。

我们来看下线程中断最重要的 3 个方法,它们都是来自 Thread 类!

1、java.lang.Thread#interrupt

中断目标线程,给目标线程发一个中断信号,线程被打上中断标记。

2、java.lang.Thread#isInterrupted()

判断目标线程是否被中断,不会清除中断标记。

3、java.lang.Thread#interrupted

判断目标线程是否被中断,会清除中断标记。

线程中断实战

我们来实例演示下线程中断如何用!

示例1(中断失败)

private static void test1() {
    Thread thread = new Thread(() -> {
        while (true) {
            Thread.yield();
        }
    });
    thread.start();
    thread.interrupt();
}

请问示例1中的线程会被中断吗?答案:不会,因为虽然给线程发出了中断信号,但程序中并没有响应中断信号的逻辑,所以程序不会有任何反应。

示例2:(中断成功)

private static void test2() {
    Thread thread = new Thread(() -> {
        while (true) {
            Thread.yield();

            // 响应中断
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("线程被中断,程序退出。");
                return;
            }
        }
    });
    thread.start();
    thread.interrupt();
}

我们给示例2加上了响应中断的逻辑,程序接收到中断信号打印出信息后返回退出。

示例3(中断失败)

private static void test3() throws InterruptedException {
    Thread thread = new Thread(() -> {
        while (true) {
            // 响应中断
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("线程被中断,程序退出。");
                return;
            }

            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                System.out.println("线程休眠被中断,程序退出。");
            }
        }
    });
    thread.start();
    Thread.sleep(2000);
    thread.interrupt();
}

示例3 sleep() 方法被中断,并输出了?线程休眠被中断,程序退出。?程序继续运行……为什么呢?

来看 sleep 的源码:

技术图片

可以看出 sleep() 方法被中断后会清除中断标记,所以循环会继续运行。。

示例4(中断成功)

private static void test4() throws InterruptedException {
    Thread thread = new Thread(() -> {
        while (true) {
            // 响应中断
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("线程被中断,程序退出。");
                return;
            }

            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                System.out.println("线程休眠被中断,程序退出。");
                Thread.currentThread().interrupt();
            }
        }
    });
    thread.start();
    Thread.sleep(2000);
    thread.interrupt();
}

示例4全部信息输出并正常退出,只是在 sleep() 方法被中断并清除标记后手动重新中断当前线程,然后程序接收中断信号返回退出

cas和aqs一文搞懂(代码片段)

JAVA多线程,面试官喜欢问的东西一些概念的东西原子性就是指该操作是不可再分的。不论是多核还是单核,具有原子性的量,同一时刻只能有一个线程来对它进行操作。简而言之,在整个操作过程中不会被线程调... 查看详情

java中的线程池如何实现,一文彻底搞懂(代码片段)

前言为什么要用线程池一键获取线程相关资料,还可获取最新java面试真题库在HotSpotVM的线程模型中,Java线程被一对一映射为内核线程。Java在使用线程执行程序时,需要调用操作系统内核的API,创建一个内核线程&... 查看详情

一文搞懂线程池中的执行原则和核心配置参数

  本文介绍下线程池的一些配置信息。  在软件开发中,池一直都是一种非常优秀的设计思想,通过建立池可以有效的利用系统资源,节约系统性能。Java中的线程池就是一种非常好的实现,从JDK1.5开始Java提... 查看详情

一文搞懂java的多线程底层逻辑,再也不怕多线程了(代码片段)

目录1、线程是什么2、启动线程3、线程池4、线程池的创建通过Executors工厂方法创建通过构造函数创建5、调试线程6、synchronized关键字没什么想说的,就是想写两次Java的,顺便送两本书,好了,开始吧1、线程是什... 查看详情

一文搞懂java的多线程底层逻辑,再也不怕多线程了(代码片段)

目录1、线程是什么2、启动线程3、线程池4、线程池的创建通过Executors工厂方法创建通过构造函数创建5、调试线程6、synchronized关键字没什么想说的,就是想写两次Java的,顺便送两本书,好了,开始吧1、线程是什... 查看详情

一文搞懂进程线程协程

前言操作系统的主要目标是执行用户程序,但也需要顾及内核之外的各种系统任务。系统由一组进程组成:操作系统进程执行系统代码,用户进程执行用户代码。问题:为什么需要进程?早期的计算机系统只允许一次执行一个程... 查看详情

一文搞懂│python中守护线程与非守护线程(代码片段)

✨目录🎈什么是守护线程🎈非守护线程🎈守护线程🎈什么是守护线程当主线程执行结束后,所有在运行的子线程都直接结束,不管子任务是否完成很多语言的垃圾收集器就运用了守护线程,去回收程... 查看详情

一文搞懂│python中守护线程与非守护线程(代码片段)

✨目录🎈什么是守护线程🎈非守护线程🎈守护线程🎈什么是守护线程当主线程执行结束后,所有在运行的子线程都直接结束,不管子任务是否完成很多语言的垃圾收集器就运用了守护线程,去回收程... 查看详情

一文让你彻底搞懂多线程(代码片段)

如果对什么是线程、什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内。用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现。说这个话其... 查看详情

一文搞懂volatile关键字的作用(代码片段)

前言Volatile关键字的作用主要有如下两个:1.线程的可见性:当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。2.顺序一致性:禁止指令重排序。一、线程可见性我们先通过一个例子来看看线程... 查看详情

一文搞懂volatile关键字的作用(代码片段)

前言Volatile关键字的作用主要有如下两个:1.线程的可见性:当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。2.顺序一致性:禁止指令重排序。一、线程可见性我们先通过一个例子来看看线程... 查看详情

一文搞懂java的多线程底层逻辑,再也不怕多线程了(代码片段)

目录1、线程是什么2、启动线程3、线程池4、线程池的创建通过Executors工厂方法创建通过构造函数创建5、调试线程6、synchronized关键字没什么想说的,就是想写两次Java的,顺便送两本书,好了,开始吧1、线程是什... 查看详情

一文带你搞懂内存泄漏!!!(代码片段)

好文推荐:作者:codelang检测内存是否泄漏非常简单,只要在任意位置调用Debug.dumpHprofData(file)即可,通过拿到hprof文件进行分析就可以知道哪里产生了泄漏,但dump的过程会suspend所有的java线程,导致用户界... 查看详情

java基础-一文搞懂位运算

  在日常的Java开发中,位运算使用的不多,使用的更多的是算数运算(+、-、*、/、%)、关系运算(<、>、<=、>=、==、!=)和逻辑运算(&&、||、!),所以相对来说对位运算不是那么熟悉,本文将以Java的位运算来... 查看详情

java基础-一文搞懂位运算

在日常的Java开发中,位运算使用的不多,使用的更多的是算数运算(+、-、*、/、%)、关系运算(<、>、<=、>=、==、!=)和逻辑运算(&&、||、!),所以相对来说对位运算不是那么熟悉,本文将以Java的位运算来详细... 查看详情

java并发一文读懂(代码片段)

目录线程实现方式方式一:实现Runnable接口方式二:实现Callable接口方式三:继承Thread类演示功能代码实现接口VS继承Thread线程机制Executor(线程执行容器)Executor(线程执行容器)实现CachedThreadPool实例Fi... 查看详情

别告诉我你连线程池都不会用~一文搞懂线程池(代码片段)

线程池作用降低资源消耗:通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗。提高响应速度:任务到达时,无需等待线程创建即可立即执行。提高线程的可管理性:线程是稀缺资源,... 查看详情

一文搞懂java并发编程模型有哪些

聊聊Java并发编程的模型有哪些并发系统同分布式系统相似并行工作者模式并行工作者模型的优点并行工作者模型的缺点1)共享状态可能会很复杂2)无状态的工作者3)任务顺序是不确定的流水线模式反应器,事件... 查看详情