1.背景

在实际开发中,我们可能会遇到终止某个线程的场景,

比如不断扫描数据库的发货订单时,这时候需停止扫描,

当然我们不能把程序关了,我们只希望停止扫描数据库这一个线程,

那么应该怎么办了?

这就可以使用线程中提供的interrupt()这个方法

2.案例演示

  1. package com.ldp.demo01;
  2.  
  3. import com.common.MyThreadUtil;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.junit.Test;
  6.  
  7. /**
  8. * @author 姿势帝-博客园
  9. * @address https://www.cnblogs.com/newAndHui/
  10. * @WeChat 851298348
  11. * @create 01/16 9:41
  12. * @description <p>
  13. * interrupt()方法的理解
  14. * 1.只是给线程设置一个打断标记,不会改变线程的实际状态
  15. * 2.打断睡眠中的线程会清除打断标记(即标记无效)
  16. * 3.实际应用中可以利用判断线程的打断标记,来判断是否继续业务.
  17. * </p>
  18. */
  19. @Slf4j
  20. public class Test03Interrupt {
  21. /**
  22. * 打断正常的线程
  23. * 1. t1.interrupt() 只是给线程设置一个打断标记,不会改变线程的实际状态
  24. */
  25. @Test
  26. public void test01() {
  27. Thread t1 = new Thread(() -> {
  28. log.info("执行中......");
  29. while (true) {
  30. }
  31. }, "t1");
  32. // 启动线程
  33. t1.start();
  34. // 查看打断状态
  35. log.info("interrupted=" + t1.isInterrupted());
  36. // 查看线程状态
  37. log.info("线程状态为:" + t1.getState());
  38. // 睡眠2秒
  39. MyThreadUtil.sleep(2);
  40. // 打断线程
  41. t1.interrupt();
  42. // 查看打断状态
  43. log.info("interrupted=" + t1.isInterrupted());
  44. // 再次查看线程状态
  45. log.info("线程状态为:" + t1.getState());
  46. // 防止主线程结束
  47. MyThreadUtil.sleep(10);
  48. }
  49.  
  50. /**
  51. * 打断处于睡眠的线程
  52. * 1. 打断睡眠中的线程会清除打断标记(即标记无效)
  53. */
  54. @Test
  55. public void test02() {
  56. Thread t1 = new Thread(() -> {
  57. while (true) {
  58. log.info("执行中......");
  59. Thread currentThread = Thread.currentThread();
  60. if (currentThread.isInterrupted()) {
  61. log.info("isInterrupted=true");
  62. break;
  63. }
  64. try {
  65. Thread.sleep(50 * 1000);
  66. } catch (InterruptedException e) {
  67. e.printStackTrace();
  68. log.info("isInterrupted=" + currentThread.isInterrupted());
  69. // 重新设置打断标记
  70. currentThread.interrupt();
  71. }
  72. }
  73. }, "t1");
  74. // 启动线程
  75. t1.start();
  76. // 睡眠2秒
  77. MyThreadUtil.sleep(2);
  78. // 打断线程
  79. t1.interrupt();
  80. // 查看打断状态
  81. log.info("isInterrupted=>" + t1.isInterrupted());
  82. // 防止主线程结束
  83. MyThreadUtil.sleep(10);
  84. }
  85.  
  86. /**
  87. * 两阶段终止
  88. * 案例:
  89. * 假设有一个主线程一直在扫描数据的订单进行发货操作,
  90. * 在页面有我们需要有暂停发货\继续发货\停止发货三个功能
  91. */
  92. @Test
  93. public void test03() {
  94. // 扫描数据线程
  95. Thread threadDataMain = new Thread(() -> {
  96. Thread currentThread = Thread.currentThread();
  97. while (true) {
  98. boolean interrupted = currentThread.isInterrupted();
  99. if (interrupted) {
  100. // 如果线程被打断就停止循环
  101. log.info("停止获取数据");
  102. break;
  103. }
  104. // 模拟读取数据数据,每次1条
  105. String order = getOrder();
  106. if (order == null) {
  107. log.info("无数据休息2秒");
  108. // 数据库无订单休息2秒
  109. try {
  110. Thread.sleep(2 * 1000);
  111. } catch (InterruptedException e) {
  112. e.printStackTrace();
  113. // 重新设置打断标记
  114. currentThread.interrupt();
  115. }
  116. continue;
  117. }
  118. // 发货线程
  119. Thread threadOrder = new Thread(() -> {
  120. log.info("订单发货中:" + order);
  121. }, "t-" + order);
  122. threadOrder.start();
  123. }
  124. }, "thread-数据库扫描主线程");
  125. threadDataMain.start();
  126.  
  127. // 模拟发货10秒后停止发货
  128. MyThreadUtil.sleep(10);
  129. threadDataMain.interrupt();
  130.  
  131. // 防止主线程结束
  132. MyThreadUtil.sleep(20);
  133. }
  134.  
  135. /**
  136. * 模拟数据库获取订单
  137. *
  138. * @return
  139. */
  140. public String getOrder() {
  141. // 模拟有时候无数据的情况
  142. // int nextInt = new Random().nextInt(10);
  143. long millis = System.currentTimeMillis();
  144. if (millis % 3 > 0) {
  145. return null;
  146. }
  147. // 3的整数倍才返回订单
  148. return "NO" + System.currentTimeMillis();
  149. }
  150. }

完美!

多线程之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. CTF反序列化wp(ciscn,nss,ctfshowweb入门)

    [CISCN 2023 华北]ez_date 题目: <?php error_reporting(0); highlight_file(__FILE__); class date{ public ...

  2. mysql ON DUPLICATE KEY UPDATE 演示

    <e>查询:INSERT INTO member_test(mem_no,flag)VALUE('111','1') 错误代码: 1062Duplicate entry '111' for ...

  3. excel计算日期天数和表格冻结首行

    excel计算日期天数和表格冻结首行 1.在单元格E35中输入公式DATEDIF(A35.B35."MD")MD表起始日期.结束日期天数差."Y" 时间段中的整 ...

  4. CF1320D Reachable Strings

    110和011互相转化,相当于就是0在连续两个1的情况下,移动两个位置 能够发现,0的位置的奇偶不会改变,且很多个0之间的相对位置不会改变 猜想考虑这个答案只跟0的奇偶性有关,下面小证一下:(注意下面 ...

  5. 全国产T3+FPGA的SPI与I2C通信方案分享

    近年来,随着中国新基建.中国制造2025规划的持续推进,单ARM处理器越来越难胜任工业现场的功能要求,特别是如今能源电力.工业控制.智慧医疗等行业,往往更需要ARM + FPGA架构的处理器平台来实现 ...

  6. 用hive或mr清洗app数据

    1.项目背景 从大量源数据中清洗出有效数据供后续程序使用. 源数据参照log.txt文件 2.项目源数据说明 9841EF7BDBDF0AC9AF42AEBB4E4F8D4F Id 12 状态1 22 ...

  7. 使用Stream流实现以List<Map<String, Object>>集合中Map的key值进行排序

    使用Stream流实现以List<Map<String, Object>>集合中Map的key值进行排序 创建一个list存入数据 List<Map<String, ...

  8. Nuxt3 的生命周期和钩子函数(十一)

    title: Nuxt3 的生命周期和钩子函数(十一) date: 2024/7/5 updated: 2024/7/5 author: cmdragon excerpt: 摘要:本文详细介绍了Nux ...

  9. vulnhub - w1r3s.v1.0.1

    vulnhub - w1r3s.v1.0.1 高质量视频教程 - b站红队笔记 靶机下载 本地环境 本机ip:192.168.157.131 w1r3s虚拟机设置NAT模式 信息收集 扫描网段得到攻击 ...

  10. FairMOT复现报错存档

    FairMOT复现 使用pip命令单独安装Cython包即可 修改下载的cython-bbox包里的setup.py里的代码 将#extra_compile_args=['-Wno-cpp'], 修改 ...