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与优雅停止一个线程的更多相关文章

  1. Java线程状态、线程start方法源码、多线程、Java线程池、如何停止一个线程

    下面将依次介绍: 1. 线程状态.Java线程状态和线程池状态 2. start方法源码 3. 什么是线程池? 4. 线程池的工作原理和使用线程池的好处 5. ThreadPoolExecutor中的 ...

  2. Java 如何正确停止一个线程

    自己在做实验性小项目的时候,发现自己遇到一个问题:如何控制线程的"死亡"? 首先,如何开启一个线程呢? 最简单的代码: public class Main { public sta ...

  3. Java并发(基础知识)—— 创建、运行以及停止一个线程

    在计算机世界,当人们谈到并发时,它的意思是一系列的任务在计算机中同时执行.如果计算机有多个处理器或者多核处理器,那么这个同时性是真实发生的:如果计算机只有一个核心处理器那么就只是表面现象. 现代所有的 ...

  4. Java多线程之interrupt()的深度研究

    近期学习Java多线程的中断机制,网上的帖子说得很浅,并没深究其原理.看了Java源码,对Java的中断机制有了略深入的理解,在这篇文章中向感兴趣的网友分享下.这篇文章主要通过一个典型例子对中断机制进 ...

  5. java如何正确停止一个线程

    Thread类中有start(), stop()方法,不过stop方法已经被废弃掉. 平时其实也有用过,共享一个变量,相当于标志,不断检查标志,判断是否退出线程 如果有阻塞,需要使用Thread的in ...

  6. java停止一个线程

    Thread类中有start(), stop()方法,不过stop方法已经被废弃掉. 平时其实也有用过,共享一个变量,相当于标志,不断检查标志,判断是否退出线程 如果有阻塞,需要使用Thread的in ...

  7. java基础---->多线程之interrupt(九)

    这里我们通过实例来学习一下java多线程中关于interrupt方法的一些知识.执者失之.我想当一个诗人的时候,我就失去了诗,我想当一个人的时候,我就失去了我自己.在你什么也不想要的时候,一切如期而来 ...

  8. java中的线程(2):如何正确停止线程之3种常见停止方式

    1.常见停止方式 自定义线程,其中含退出标志位,在run中判断它. 使用interrupt()方法中断线程 使用stop方法暴力终止(已经弃用) 2.使用标志位 class TestThread ex ...

  9. java中的线程(2):如何正确停止线程之2种常见停止方式

    1.常见停止方式 结束run函数,run中含退出标志位. 使用interrupt()方法中断线程 使用stop方法暴力终止(已经弃用) 2.结束run class TestThread extends ...

  10. 多线程之interrupt

    1.interrupt()作为中断程序,并不会直接终止运行,而是设置中断状态,由线程自己处理中断.可以选择终止线程.等待新任务或继续执行. 2.interrupt()经常用于中断处于堵塞状态的的线程, ...

随机推荐

  1. 「C++」简单模拟

    这是一个公式: \[F_n=\dfrac{\left(\frac{1+\sqrt{5}}{2}\right)^n-\left(\frac{1-\sqrt{5}}{2}\right)^n}{\sqrt{ ...

  2. radis简单学习笔记

    原来写接口只用了本机缓存cache 来学习一下radis,用法应该跟cache一样吧,为了配套负载均衡的多服务器是多个服务器都可以读取缓存 一.下载 找了好长时间 github有的时候能上有的时候就上 ...

  3. Docker安装mysql配置my.cnf并挂载到外部机器

    1.环境准备,创建外部挂载文件夹conf,data,log mkdir -p /data/dockerdata/mysql3306/{conf,data,log} 2.在/data/dockerdat ...

  4. Linux中的IDR机制

    # Linux中的IDR机制 背景 最近在学习 Linux的i2c子系统,看到代码中有关于IDR的调用.了解了一下有关的文档,发现是用来管理指针(对象实例). //based on linux V3. ...

  5. uboot 修改代码 增加 环境变量

    --- title: uboot修改代码增加环境变量 date: 2019-12-27 21:26:39 categories: tags: - uboot --- 以"tftp下载kern ...

  6. Markdown 文章 跳转

    背景 在查阅一些文档的时候,一些比较优秀博客在文章中是带有目录的,点击就会跳转到指定的锚点. 在本人的某些文章中,也想尝试这样的效果. 做法 实现这样的效果有2种做法(不同之处在于 超链接的写法不同) ...

  7. 【论文阅读】Exploring the Limitations of Behavior Cloning for Autonomous Driving

    Column: January 16, 2022 11:11 PM Last edited time: January 21, 2022 12:23 PM Sensor/组织: 1 RGB Statu ...

  8. 卷积神经网络中nn.Conv2d()和nn.MaxPool2d()以及卷积神经网络实现minist数据集分类

    卷积神经网络中nn.Conv2d()和nn.MaxPool2d() 卷积神经网络之Pythorch实现: nn.Conv2d()就是PyTorch中的卷积模块 参数列表 参数 作用 in_channe ...

  9. win10 VMware 关闭虚拟机失败导致再打开时显示连接不上虚拟机的一种解决方法

    VMware关闭虚拟机失败,强行关闭后,再次打开VMware,打开虚拟机时提示连接不上虚拟机,没有访问权限. 先试了退出后,用管理员权限打开,无果. 然后从网上查资料,cmd->services ...

  10. 关于Windows 10 LTSC 2019无法安装Edge的解决方案

    最近新换了Windows 10 LTSC 2019系统,使用体验干净且流畅,但是在更新Edge时遇到了问题:系统内装的是9x版本的Edge浏览器,并且提示更新错误,有system level方面的问题 ...