【并发设计模式】聊聊两阶段终止模式如何优雅终止线程
在软件设计中,抽象出了23种设计模式,用以解决对象的创建、组合、使用三种场景。在并发编程中,针对线程的操作,也抽象出对应的并发设计模式。
- 两阶段终止模式- 优雅停止线程
- 避免共享的设计模式- 只读、Copy-on-write、Thread-Specific Storage
- 多线程版本的if模式
- 多线程分工模式 (Thread-per-Message 、Worker Thread、生产者-消费者模式)
从今天开始我们会开始逐篇讲解这几种并发设计模式。
最简单的方式其实就是调用线程的Stop方法,但是这个方法不推荐使用,原因是会直接将线程杀死。对于业务是不允许的。太粗暴了。
两阶段终止模式
两阶段终止模式其实就是将线程终止的过程分成两个过程。
第一个过程T1向线程T2发送终止指令,第二个过程T2响应终止指令。

但是本身线程想进入终止状态,那么必然要从运行状态转换,但是这个线程可能是休眠状态,block、wait、time_wait 三种状态。所以需要使用Thread类的interrupt()方法 将线程从休眠状态转换到runnable状态。然后我们设置一个中断位,T2线程检查到需要终止就会直接停止。
一个案例
public class Proxy {private boolean isStart = false;// 对于stop的方法的修改 需要被start()方法 获取到,变量的可见性 private volatile boolean termial = false;private Thread runTask;synchronized void start () {runTask = new Thread(() -> {if (isStart) {return;}isStart = true;while (!Thread.currentThread().isInterrupted() || !termial) {try {System.out.println("send->监控数据>监控平台");TimeUnit.SECONDS.sleep(2);} catch (Exception e) {Thread.currentThread().interrupt();e.printStackTrace();}}isStart = false;System.out.println(Thread.currentThread().getName() + " stop");});runTask.start();}synchronized void stop () {runTask.interrupt();termial = true;}}
终止线程池
对于终止线程池,shutdown()和shutdownNow() 前者其实会将线程池在处理以及阻塞队列中的任务处理完毕,后者会直接拒绝执行任何任务, shutdownNow的返回值是等得队列中未被执行的任务。所以在实际的使用中不推荐直接使用这两个方法。更优的方法其实是
pool.shutdown();boolean terminated = false;while (!terminated) {pool.awaitTermination(100,TimeUnit.SECONDS);}
两阶段终止模式是一种应用很广泛的并发设计模式,在 Java 语言中使用两阶段终止模式来 优雅地终止线程,需要注意两个关键点: 一个是仅检查终止标志位是不够的,因为线程的状态 可能处于休眠态;另一个是仅检查线程的中断状态也是不够的,因为我们依赖的第三方类库很 可能没有正确处理中断异常, 例如第三方类库在捕获到 Thread.sleep() 方法抛出的中断异常 后,没有重新设置线程的中断状态,那么就会导致线程不能够正常终止。所以我们可以自定义 线程的终止标志位用于终止线程。
小结
好了本篇主要介绍到这里。其实两阶段终止模式主要用以在终止线程的时候,
使用场景
- 安全地终止线程,比如释放该释放的资源;
- 要确保终止处理逻辑在线程结束之前一定会执行时,可使用该方法;
相关文章:
【并发设计模式】聊聊两阶段终止模式如何优雅终止线程
在软件设计中,抽象出了23种设计模式,用以解决对象的创建、组合、使用三种场景。在并发编程中,针对线程的操作,也抽象出对应的并发设计模式。 两阶段终止模式- 优雅停止线程避免共享的设计模式- 只读、Copy-on-write、Thread-Spec…...
Java实现非对称加密【详解】
Java实现非对称加密 1. 简介2. 非对称加密算法--DH(密钥交换)3. 非对称加密算法--RSA非对称加密算法--EIGamal5. 总结6 案例6.1 案例16.2 案例2 1. 简介 公开密钥密码学(英语:Public-key cryptography)也称非对称式密…...
simulinkveristandlabview联合仿真——模型导入搭建人机界面
目录 1.软件版本 2.搭建simulink仿真模型 编译错误 3.导入veristand并建立工程 4.veristand导入labview labview显示veristand工程数据 labview设置veristand工程数据 运行labview工程 1.软件版本 matlab2020a,veristand2020 R4,labview2020 SP…...
k8s中Helm工具实践
k8s中Helm工具实践 1)安装redis-cluster 先搭建一个NFS的SC(只需要SC,不需要pvc),具体步骤此文档不再提供,请参考前面相关章节。 下载redis-cluster的chart包 helm pull bitnami/redis-cluster --untar…...
推荐算法架构7:特征工程(吊打面试官,史上最全!)
系列文章,请多关注 推荐算法架构1:召回 推荐算法架构2:粗排 推荐算法架构3:精排 推荐算法架构4:重排 推荐算法架构5:全链路专项优化 推荐算法架构6:数据样本 推荐算法架构7:特…...
Web前端 ---- 【Vue】vue路由守卫(全局前置路由守卫、全局后置路由守卫、局部路由path守卫、局部路由component守卫)
目录 前言 全局前置路由守卫 全局后置路由守卫 局部路由守卫之path守卫 局部路由守卫之component守卫 前言 本文介绍Vue2最后的知识点,关于vue的路由守卫。也就是鉴权,不是所有的组件任何人都可以访问到的,需要权限,而根据权限…...
uniapp点击tabbar之前做判断
在UniApp中,可以通过监听 tabBar 的 click 事件来在点击 tabBar 前做判断。具体步骤如下: 在 pages.json 文件中配置 tabBar,例如: {"pages":[{"path":"pages/home/home","name":"h…...
DLLNotFoundException:xxx tolua... 错误打印
DLLNotFoundException:xxx tolua... 错误打印 一、DLLNotFoundException介绍二、Plugins文件夹文件目录结构如下: 三、Plugins中的Android文件夹四、Plugins中的IOS文件夹这里不说了没测试过不过原理应该也是选择对应的平台即可五、Plugins中的x86和X86_64文件夹 一…...
Python量化投资——金融数据最佳实践: 使用qteasy+tushare搭建本地金融数据仓库并定期批量更新【附源码】
用qteasytushare实现金融数据本地化存储及访问 目的什么是qteasy什么是tushare为什么要本地化使用qteasy创建本地数据仓库qteasy支持的几种本地化仓库类型配置本地数据仓库配置tushare 的API token 配置本地数据源 —— 用MySQL数据库作为本地数据源下载金融历史数据 数据的定期…...
【投稿】北海 - Rust与面向对象(二)
模板方法 Rust提供了trait,类似于面向对象的接口,不同的是,将传统面向对象的虚函数表从对象中分离出来,trait仍然是一个函数表,只不过是独立的,它的参数self指针可以指向任何实现了该trait的结构。 从对象中…...
HarmonyOS构建第一个ArkTS应用(FA模型)
构建第一个ArkTS应用(FA模型) 创建ArkTS工程 若首次打开DevEco Studio,请点击Create Project创建工程。如果已经打开了一个工程,请在菜单栏选择File > New > Create Project来创建一个新工程。 选择Application应用开发&a…...
阿里云 ARMS 应用监控重磅支持 Java 21
作者:牧思 & 山猎 前言 今年的 9 月 19 日,作为最新的 LTS (Long Term Support) Java 版本,Java 21 正式 GA,带来了不少重量级的更新,详情请参考 The Arrival of Java 21 [ 1] 。虽然目前 Java 11 和 Java 17 都…...
C++ 类的析构函数和构造函数
构造函数 类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。主要用来在创建对象时初始化对象即为对象成员变量赋初始值。 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用…...
STM32——CAN协议
文章目录 一.CAN协议的基本特点1.1 特点1.2 电平标准1.3 基本的五个帧1.4 数据帧 二.数据帧解析2.1 帧起始和仲裁段2.2 控制段2.3 数据段和CRC段2.4 ACK段和帧结束 三.总线仲裁四.位时序五.STM32CAN控制器原理与配置5.1 STM32CAN控制器介绍5.2 CAN的模式5.3 CAN框图 六 手册寄存…...
数据结构-如何巧妙实现一个栈?逐步解析与代码示例
文章目录 引言1.栈的基本概念2.选择数组还是链表?3. 定义栈结构4.初始化栈5.压栈操作6.弹栈操作7.查看栈顶和判断栈空9.销毁栈操作10.测试并且打印栈内容栈的实际应用结论 引言 栈是一种基本但强大的数据结构,它在许多算法和系统功能中扮演着关键角色。…...
web前端之拖拽API、vue3实现图片上传拖拽排序、拖放、投掷、复制、若依、vuedraggable
MENU vue2html5原生dom原生JavaScript实现跨区域拖放vue2实现跨区域拖放vue2mousedown实现全屏拖动,全屏投掷vue3element-plusvuedraggable实现图片上传拖拽排序vue2transition-group实现拖动排序原生拖拽排序 vue2html5原生dom原生JavaScript实现跨区域拖放 关键代…...
第11章 GUI Page403~405 步骤三 设置滚动范围
运行效果: 源代码: /**************************************************************** Name: wxMyPainterApp.h* Purpose: Defines Application Class* Author: yanzhenxi (3065598272qq.com)* Created: 2023-12-21* Copyright: yanzhen…...
【Spring Security】打造安全无忧的Web应用--使用篇
🥳🥳Welcome Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于Spring Security的相关操作吧 目录 🥳🥳Welcome Huihuis Code World ! !🥳🥳 一.Spring Security中的授权是…...
体验一下 CodeGPT 插件
体验一下 CodeGPT 插件 0. 背景1. CodeGPT 插件安装2. CodeGPT 插件基本配置3. (可选)CodeGPT 插件预制提示词原始配置(英文)4. CodeGPT 插件预制提示词配置(中文)5. 简单验证一下 0. 背景 看到B站Up主 “wwwzhouhui” 一个关于 CodeGPT 的视频,感觉挺有意思&#…...
深度学习 | 基础卷积神经网络
卷积神经网络是人脸识别、自动驾驶汽车等大多数计算机视觉应用的支柱。可以认为是一种特殊的神经网络架构,其中基本的矩阵乘法运算被卷积运算取代,专门处理具有网格状拓扑结构的数据。 1、全连接层的问题 1.1、全连接层的问题 “全连接层”的特点是每个…...
当机器人遇见城市:江南北如何重塑武汉的智能生活图景
城市,是人类文明的结晶,也是科技创新的试验场。在武汉这座英雄的城市,一场由江南北(武汉)信息技术有限公司(简称“江南北机器人”)引领的智能革命,正悄然改变着市民的日常生活与城市…...
小米路由器R3G刷机实战:从官方固件到蜜罐版MT工具箱的保姆级避坑指南
小米路由器R3G深度改造指南:解锁第三方固件的完整路线图 当你盯着家里那台性能日渐吃紧的小米路由器R3G时,是否想过它其实蕴藏着未被发掘的潜力?这款发布于数年前的中端路由器,凭借MT7621双核芯片和128MB内存的硬件基础࿰…...
LibreCAD符号库创建终极指南:快速构建您的专业CAD图库
LibreCAD符号库创建终极指南:快速构建您的专业CAD图库 【免费下载链接】LibreCAD LibreCAD is a cross-platform 2D CAD program. It can read DXF and write DXF/PDF/SVG files, with basic support for DWG reading. It supports point/line/circle/ellipse/parab…...
哈佛医学院:空间组学范式转变!单细胞分子谱→多细胞功能
摘要 空间分辨单细胞技术能够实现细胞的原位分子谱分析,但能够同时发现多细胞空间模式并表征其分子程序的计算方法仍十分有限。本文提出SpatialQuery框架,可同时识别细胞基序(即反复出现的多细胞共定位模式)并开展基序靶向的分子分析。该框架通过差异表达分析挖掘受空间微…...
开源AI智能体QClaw-Mimic:用个人数据微调大模型打造专属数字分身
1. 项目概述:一个能“模仿”你的开源智能体最近在GitHub上看到一个挺有意思的项目,叫QClaw-Mimic。光看名字,Mimic(模仿)这个词就挺抓人的。点进去一看,果然,这是一个旨在通过分析你的历史对话数…...
ArcGIS实战:手把手教你拼接与裁剪全国10米建筑高度栅格数据(以武汉为例)
ArcGIS实战:全国10米建筑高度栅格数据的精准处理与武汉应用 引言:高精度建筑数据的价值与挑战 城市规划师李明最近在武汉某旧城改造项目中遇到了棘手问题——传统30米分辨率的建筑高度数据无法准确反映老城区复杂的建筑形态差异。当他尝试获取更高精度的…...
DIY蓝牙街机摇杆:从零打造无线复古游戏控制器
1. 项目概述与核心思路作为一个玩了二十多年街机,也折腾了十几年硬件的“老炮儿”,我始终觉得,有些东西的味道是数字模拟不出来的。比如,用键盘或现代手柄玩《拳皇97》或《合金弹头》,总觉得少了点灵魂——那“咔哒咔哒…...
luceda ipkiss实战:利用MZI Lattice Filter实现可调谐波分复用器
1. MZI晶格滤波器基础与可调谐波分复用原理 马赫曾德干涉仪(MZI)晶格结构是集成光子学中最经典的多功能器件之一。我第一次接触这种结构时,就被它优雅的对称性和强大的可重构性所吸引。本质上,它通过级联多个MZI单元形成周期性结构…...
RT-Thread aarch64虚拟平台文件系统移植实战:从QEMU virt到LittleFS
1. 项目概述与核心价值最近在折腾RT-Thread的aarch64虚拟平台,特别是qemu-virt64-aarch64这个BSP(Board Support Package,板级支持包)上的文件系统支持。这看起来像是一个很具体的移植工作,但实际上,它触及…...
深入JPEG文件结构:用Python和十六进制编辑器‘解剖’一张图片,理解tiny_jpeg.h的写入逻辑
逆向工程JPEG:用Python和十六进制工具解析tiny_jpeg.h的编码逻辑 当你用手机拍下一张照片,或是从网上下载一张图片时,这些图像大多以JPEG格式存储。但你是否好奇过,这个看似简单的.jpg文件内部究竟隐藏着怎样的结构?本…...
