多线程之interrupt与优雅停止一个线程
1.背景
在实际开发中,我们可能会遇到终止某个线程的场景,
比如不断扫描数据库的发货订单时,这时候需停止扫描,
当然我们不能把程序关了,我们只希望停止扫描数据库这一个线程,
那么应该怎么办了?
这就可以使用线程中提供的interrupt()这个方法
2.案例演示
- package com.ldp.demo01;
- import com.common.MyThreadUtil;
- import lombok.extern.slf4j.Slf4j;
- import org.junit.Test;
- /**
- * @author 姿势帝-博客园
- * @address https://www.cnblogs.com/newAndHui/
- * @WeChat 851298348
- * @create 01/16 9:41
- * @description <p>
- * interrupt()方法的理解
- * 1.只是给线程设置一个打断标记,不会改变线程的实际状态
- * 2.打断睡眠中的线程会清除打断标记(即标记无效)
- * 3.实际应用中可以利用判断线程的打断标记,来判断是否继续业务.
- * </p>
- */
- @Slf4j
- public class Test03Interrupt {
- /**
- * 打断正常的线程
- * 1. t1.interrupt() 只是给线程设置一个打断标记,不会改变线程的实际状态
- */
- @Test
- public void test01() {
- Thread t1 = new Thread(() -> {
- log.info("执行中......");
- while (true) {
- }
- }, "t1");
- // 启动线程
- t1.start();
- // 查看打断状态
- log.info("interrupted=" + t1.isInterrupted());
- // 查看线程状态
- log.info("线程状态为:" + t1.getState());
- // 睡眠2秒
- MyThreadUtil.sleep(2);
- // 打断线程
- t1.interrupt();
- // 查看打断状态
- log.info("interrupted=" + t1.isInterrupted());
- // 再次查看线程状态
- log.info("线程状态为:" + t1.getState());
- // 防止主线程结束
- MyThreadUtil.sleep(10);
- }
- /**
- * 打断处于睡眠的线程
- * 1. 打断睡眠中的线程会清除打断标记(即标记无效)
- */
- @Test
- public void test02() {
- Thread t1 = new Thread(() -> {
- while (true) {
- log.info("执行中......");
- Thread currentThread = Thread.currentThread();
- if (currentThread.isInterrupted()) {
- log.info("isInterrupted=true");
- break;
- }
- try {
- Thread.sleep(50 * 1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- log.info("isInterrupted=" + currentThread.isInterrupted());
- // 重新设置打断标记
- currentThread.interrupt();
- }
- }
- }, "t1");
- // 启动线程
- t1.start();
- // 睡眠2秒
- MyThreadUtil.sleep(2);
- // 打断线程
- t1.interrupt();
- // 查看打断状态
- log.info("isInterrupted=>" + t1.isInterrupted());
- // 防止主线程结束
- MyThreadUtil.sleep(10);
- }
- /**
- * 两阶段终止
- * 案例:
- * 假设有一个主线程一直在扫描数据的订单进行发货操作,
- * 在页面有我们需要有暂停发货\继续发货\停止发货三个功能
- */
- @Test
- public void test03() {
- // 扫描数据线程
- Thread threadDataMain = new Thread(() -> {
- Thread currentThread = Thread.currentThread();
- while (true) {
- boolean interrupted = currentThread.isInterrupted();
- if (interrupted) {
- // 如果线程被打断就停止循环
- log.info("停止获取数据");
- break;
- }
- // 模拟读取数据数据,每次1条
- String order = getOrder();
- if (order == null) {
- log.info("无数据休息2秒");
- // 数据库无订单休息2秒
- try {
- Thread.sleep(2 * 1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- // 重新设置打断标记
- currentThread.interrupt();
- }
- continue;
- }
- // 发货线程
- Thread threadOrder = new Thread(() -> {
- log.info("订单发货中:" + order);
- }, "t-" + order);
- threadOrder.start();
- }
- }, "thread-数据库扫描主线程");
- threadDataMain.start();
- // 模拟发货10秒后停止发货
- MyThreadUtil.sleep(10);
- threadDataMain.interrupt();
- // 防止主线程结束
- MyThreadUtil.sleep(20);
- }
- /**
- * 模拟数据库获取订单
- *
- * @return
- */
- public String getOrder() {
- // 模拟有时候无数据的情况
- // int nextInt = new Random().nextInt(10);
- long millis = System.currentTimeMillis();
- if (millis % 3 > 0) {
- return null;
- }
- // 3的整数倍才返回订单
- return "NO" + System.currentTimeMillis();
- }
- }
完美!
多线程之interrupt与优雅停止一个线程的更多相关文章
- Java线程状态、线程start方法源码、多线程、Java线程池、如何停止一个线程
下面将依次介绍: 1. 线程状态.Java线程状态和线程池状态 2. start方法源码 3. 什么是线程池? 4. 线程池的工作原理和使用线程池的好处 5. ThreadPoolExecutor中的 ...
- Java 如何正确停止一个线程
自己在做实验性小项目的时候,发现自己遇到一个问题:如何控制线程的"死亡"? 首先,如何开启一个线程呢? 最简单的代码: public class Main { public sta ...
- Java并发(基础知识)—— 创建、运行以及停止一个线程
在计算机世界,当人们谈到并发时,它的意思是一系列的任务在计算机中同时执行.如果计算机有多个处理器或者多核处理器,那么这个同时性是真实发生的:如果计算机只有一个核心处理器那么就只是表面现象. 现代所有的 ...
- Java多线程之interrupt()的深度研究
近期学习Java多线程的中断机制,网上的帖子说得很浅,并没深究其原理.看了Java源码,对Java的中断机制有了略深入的理解,在这篇文章中向感兴趣的网友分享下.这篇文章主要通过一个典型例子对中断机制进 ...
- java如何正确停止一个线程
Thread类中有start(), stop()方法,不过stop方法已经被废弃掉. 平时其实也有用过,共享一个变量,相当于标志,不断检查标志,判断是否退出线程 如果有阻塞,需要使用Thread的in ...
- java停止一个线程
Thread类中有start(), stop()方法,不过stop方法已经被废弃掉. 平时其实也有用过,共享一个变量,相当于标志,不断检查标志,判断是否退出线程 如果有阻塞,需要使用Thread的in ...
- java基础---->多线程之interrupt(九)
这里我们通过实例来学习一下java多线程中关于interrupt方法的一些知识.执者失之.我想当一个诗人的时候,我就失去了诗,我想当一个人的时候,我就失去了我自己.在你什么也不想要的时候,一切如期而来 ...
- java中的线程(2):如何正确停止线程之3种常见停止方式
1.常见停止方式 自定义线程,其中含退出标志位,在run中判断它. 使用interrupt()方法中断线程 使用stop方法暴力终止(已经弃用) 2.使用标志位 class TestThread ex ...
- java中的线程(2):如何正确停止线程之2种常见停止方式
1.常见停止方式 结束run函数,run中含退出标志位. 使用interrupt()方法中断线程 使用stop方法暴力终止(已经弃用) 2.结束run class TestThread extends ...
- 多线程之interrupt
1.interrupt()作为中断程序,并不会直接终止运行,而是设置中断状态,由线程自己处理中断.可以选择终止线程.等待新任务或继续执行. 2.interrupt()经常用于中断处于堵塞状态的的线程, ...
随机推荐
- CTF反序列化wp(ciscn,nss,ctfshowweb入门)
[CISCN 2023 华北]ez_date 题目: <?php error_reporting(0); highlight_file(__FILE__); class date{ public ...
- mysql ON DUPLICATE KEY UPDATE 演示
<e>查询:INSERT INTO member_test(mem_no,flag)VALUE('111','1') 错误代码: 1062Duplicate entry '111' for ...
- excel计算日期天数和表格冻结首行
excel计算日期天数和表格冻结首行 1.在单元格E35中输入公式DATEDIF(A35.B35."MD")MD表起始日期.结束日期天数差."Y" 时间段中的整 ...
- CF1320D Reachable Strings
110和011互相转化,相当于就是0在连续两个1的情况下,移动两个位置 能够发现,0的位置的奇偶不会改变,且很多个0之间的相对位置不会改变 猜想考虑这个答案只跟0的奇偶性有关,下面小证一下:(注意下面 ...
- 全国产T3+FPGA的SPI与I2C通信方案分享
近年来,随着中国新基建.中国制造2025规划的持续推进,单ARM处理器越来越难胜任工业现场的功能要求,特别是如今能源电力.工业控制.智慧医疗等行业,往往更需要ARM + FPGA架构的处理器平台来实现 ...
- 用hive或mr清洗app数据
1.项目背景 从大量源数据中清洗出有效数据供后续程序使用. 源数据参照log.txt文件 2.项目源数据说明 9841EF7BDBDF0AC9AF42AEBB4E4F8D4F Id 12 状态1 22 ...
- 使用Stream流实现以List<Map<String, Object>>集合中Map的key值进行排序
使用Stream流实现以List<Map<String, Object>>集合中Map的key值进行排序 创建一个list存入数据 List<Map<String, ...
- Nuxt3 的生命周期和钩子函数(十一)
title: Nuxt3 的生命周期和钩子函数(十一) date: 2024/7/5 updated: 2024/7/5 author: cmdragon excerpt: 摘要:本文详细介绍了Nux ...
- vulnhub - w1r3s.v1.0.1
vulnhub - w1r3s.v1.0.1 高质量视频教程 - b站红队笔记 靶机下载 本地环境 本机ip:192.168.157.131 w1r3s虚拟机设置NAT模式 信息收集 扫描网段得到攻击 ...
- FairMOT复现报错存档
FairMOT复现 使用pip命令单独安装Cython包即可 修改下载的cython-bbox包里的setup.py里的代码 将#extra_compile_args=['-Wno-cpp'], 修改 ...