线程的“结束”

news2025/7/4 14:17:16

【一道概率很高的面试题】:

  • 如何优雅的结束一个线程?
    上传一个大文件,正在处理费时的计算,如何优雅的结束这个线程呢?

【stop方法】:

【为何不建议使用stop呢?】:
因为很容易产生数据不一致的问题;
stop方法不管你线程处于什么状态,如果持有很多把锁,它会二话不说释放所有的锁,并且不会做善后的工作。原先的锁如果是为了数据的一致性,那么使用stop有可能就会打破数据的一致性。

 public class T01_Stop {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            while (true) {
                System.out.println("go on");
                SleepHelper.sleepSeconds(1);
            }
        });

        t.start();

        SleepHelper.sleepSeconds(5);

        t.stop();  //不建议大家使用。
    }
}

在这里插入图片描述

【 suspend_resume 】:

【这两个方法被废掉的原因】:
原因和stop非常的类似 , 万一暂停的瞬间持有一把锁 , 这一把锁是不会被释放的,如果你忘记了恢复,那么就缔造出了一把《永恒的锁》。所以也是会产生数据不一致的问题的。

public class T02_Suspend_Resume {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            while (true) {
                System.out.println("go on");
                SleepHelper.sleepSeconds(1);
            }
        });

        t.start();

        SleepHelper.sleepSeconds(5);

        t.suspend();  //暂停;
        SleepHelper.sleepSeconds(3);
        t.resume();  //恢复执行。
    }
}

【volatile结束线程】:

【不太适合的情况】:
循环中有个数统计的计数器。
循环中有wait、recv、accept等方法,wait会阻塞住,不能进行下一次循环,也无法结束。
【适合的情况】:
不太依赖中间的状态——如上传数据,多上传一些 / 少上传一些 都不影响的这种情况。

public class T03_VolatileFlag {

    private static volatile boolean running = true;

    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            long i = 0L;
            while (running) {
                //wait recv accept
                i++;
            }

            System.out.println("end and i = " + i); //4168806262 4163032200
        });

        t.start();

        SleepHelper.sleepSeconds(1);

        running = false;
    }
}

【interrupt结束线程】:

//interrupt比volatile更加优雅一些 , 因为如果是volatile的话 , 中间有一些wait / sleep 的话 , 你是停不了的 , 无法跳到下一次循环。但如果是interrupt的话,你只要在sleep / wait 里面处理 InterruptedException 也可以正确的结束这个线程。
【仍有缺点】:
10个元素的容器 , 精确到第5个 , 这个也是无法达到的!!!
【这种情况如何正常结束呢?】:
必须生产者Thread和外面打断它的Thread , 两者配合才可以。
【其他方法】:
内部线程进行定时的检查 , 每隔多长时间检查一次标志位 , 每经过一次循环检查一次标志位。

/**
 * interrupt是设定标志位
 */
public class T04_Interrupt_and_NormalThread {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            while (!Thread.interrupted()) {   //只要标记位没被设置,我就一直循环~ ~ ~
                //sleep wait
            }

            System.out.println("t1 end!");
        });

        t.start();

        SleepHelper.sleepSeconds(3);

        t.interrupt();
    }
}
public class T05_InterruptAndPark {
    public static void main(String[] args) {

        Thread t = new Thread(() -> {
            System.out.println("1");
            LockSupport.park();
            System.out.println("2");
        });

        t.start();

        SleepHelper.sleepSeconds(2);

        t.interrupt();
    }
}

【阶段总结】:

【volatile 和 interrupt】:
总之,你不依赖于中间精确的次数和精确的时间的话 , 它俩都行。

【结束线程的方法】:

  1. 自然结束(能自然结束就尽量自然结束)
  2. stop() suspend() resume()
  3. volatile标志
    1. 不适合某些场景(比如还没有同步的时候,线程做了阻塞操作,没有办法循环回去)
    2. 打断时间也不是特别精确,比如一个阻塞容器,容量为5的时候结束生产者,
      但是,由于volatile同步线程标志位的时间控制不是很精确,有可能生产者还继续生产一段儿时间
  4. interrupt() and isInterrupted(比较优雅)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/7159.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【附源码】计算机毕业设计JAVA成绩分析系统

【附源码】计算机毕业设计JAVA成绩分析系统 目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: JAVA mybati…

ORA-01940 无法删除当前已连接的用户之解决方案(脚本)

第一部分:配置数据库连接 1. 安装ODBC yum -y install unixODBC unixODBC-devel 2. 安装Oracle-instantclient #以下所有操作使用root账号执行 #创建目录 mkdir -p /opt/oracle cd /opt/oracle #下载odbc安装包 wget https://download.oracle.com/otn_software…

计算机毕业设计ssm+vue基本微信小程序的好物推荐分享系统

项目介绍 我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,好物分享系统小程序被用户普遍使用,为方便用户能够可以随时进行好物分享系统小程序的数据信息管理,特开发了基于好物分…

做食品能入驻Lazada吗?带你解锁东南亚当地热销及需求食品系列

中国的电商领域已经趋于饱和状态,中国食品电商领域已经呈现出存量的趋势了,例如:良品铺子、三只松鼠、百草味、口水娃、盼盼等国内知名品牌已经占比了国内大部分的市场份额,跟着巨头抢市场 无疑是很难的,那么中国这么多…

红外线热像仪的热成像质量介绍

摘要 毫无疑问,你在过去几年的某个时候,购买了数位相机来更换旧的胶卷相机。你的购买可能受到你的信念的影响,即在尝试判断提供的所有相机选择之间的图像质量时,像素数是最重要的规格。 任何阅读过消费者报告及其对数位相机的详…

CVE-2020-1472-ZeroLogon复现

CVE-2020-1472-ZeroLogon复现 简介 Netlogon使用的AES认证算法中的vi向量默认为0,导致攻击者可以绕过认证,同时其设置域控密码的远 程接口也使用了该函数,导致可以将域控中保存在AD中的管理员password设置为空 影响版本 Windows Server 2…

大牛耗时两年完成的实战手册。Elasticsearch实战,掌握这些刚刚好!

记得刚接触Elasticsearch的时候,没找啥资料,直接看了遍Elasticsearch的中文官方文档,中文文档很久没更新了,一直都是2.3的版本。最近又重新看了遍6.0的官方文档,由于官方文档介绍的内容比较多,每次看都很费…

10.基础备份与时间点恢复

目录 基础备份 时间点恢复 时间线 基础备份与时间线都是为了时间点恢复。 基础备份 基础备份的目的是备份当前的数据库集簇的快照,结合归档日志一起可以恢复至任意的时间点。 基础备份通过pg_start_backup命令开始为基础备份做准备,它会: 强制进行整…

[附源码]java毕业设计基于web的停车收费管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

dot net 杂谈之一

文章目录一、使用vscode开发.net core程序二、创建解决方案三、反射3.1 反射应用场景一3.2 反射应用场景二一、使用vscode开发.net core程序 安装如下插件: 1、vscode-solution-explorer 2、.NET Core Extension Pack 3、搜索nuget工具包并安装 二、创建解决方案…

股票l2数据接口中的逐单跟逐笔是什么意思?

股票l2数据接口中的逐单跟逐笔是什么意思? 【逐单统计】是按成交委托单资金流转情况来统计,特大资金买卖差大单资金买卖差中单资金买卖差小单资金买卖差0。是双向统计,对于每单交易同时统计买卖双方,一定程度上反应了资金在不同类…

Redis+AOP实现一个可通用的分布式锁——改进

目录前言方案改进思考与总结前言 上一次利用Redis分布式锁解决了一个并发问题: 上篇:利用Redis分布式锁解决集群服务器定时任务重复执行问题 代码可以直接从上篇文章中拿到,本篇文章仅对上次文章内容做进一步改进 主要思想是:利…

一篇读懂|Linux系统平均负载

我们经常会使用 top 命令来查看系统的性能情况,在 top 命令的第一行可以看到 load average 这个数据,如下图所示: load average 包含 3 列,分别表示 1 分钟、5 分钟和 15 分钟的 系统平均负载。 对于系统平均负载这个数值&#x…

红杉官网已删长文:伴随SBF一路走来的救世主情结(上)

每个创业公司都有一个创业故事。苹果是洛斯阿尔托斯车库里的两个黑客。谷歌是斯坦福大学宿舍里的两个研究生。而Alameda Research是伯克利公寓里做着加密货币交易的一个人。这个人叫山姆班克曼弗里德,朋友们都叫他SBF。然而,他所做的交易——最终催生了加…

ERP系统如何改善企业的业务?

ERP代表 "企业资源计划",指的是企业用来计划和管理日常活动的一种软件或系统,如供应链、制造、服务、财务和其他流程。ERP系统可用于自动化和简化整个企业或组织的个别活动,如会计和采购、项目管理、客户关系管理、风险管理、合规和…

springboot常用组件的集成

目录 springboot常用组件的集成 1.创建项目 2. web服务器配置 3. 配置数据库 4. 配置mybatis 5. 开启事务 6.aop配置 7. pagehelper分页 3. druid数据库连接池 4. 集成redis 编写一个controller用于测试 2.手动装配redis 1.创建项目 1.idea创建项目 创建步骤 &am…

PDF文档编辑Acrobat Pro DC

acrobat dc2022不仅可以轻松的帮助用户打开任意的PDF格式文件,还能随意的对其进行编辑、压缩、合并、剪裁、旋转。删除、分割、重新排序页面等操作。全新的统一分享体验使您能够跨桌面,移动和Web进行文档协作。共享PDF链接以查看或评论。在任何设备上的任…

初识jQuery

jQuery简介 What is jQuery? jQuery is a fast, small, and feature-rich JavaScript library. It makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitud…

【附源码】计算机毕业设计JAVA宠物医院管理

【附源码】计算机毕业设计JAVA宠物医院管理 目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: JAVA mybati…

经典动画库 animate.css 的应用

一、animate.css animate.css::Animate.css 就像嗑水那么简单的CSS动画。 官网:Redirecting to Animate.css Animate.css是一个纯CSS动画库,其核心技术使用了 CSS3 里的 keyframes 和 animation。 不兼容IE10以下的 IE 浏览器。…