Java多线程-线程中止
不正确的线程中止-Stop
Stop:中止线程,并且清除监控器锁的信息,但是可能导致
线程安全问题,JDK不建议用。
Destroy: JDK未实现该方法。
/** * @author simon */ public class StopThread extends Thread { private int i = 0, j = 0; @Override public void run() { synchronized (this) { // 增加同步锁,确保线程安全 ++i; try { // 休眠10秒,模拟耗时操作 Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } ++j; } } /** * 打印i和j */ public void print() { System.out.println("i=" + i + " j=" + j); } }
/** * @author simon * 示例3 - 线程stop强制性中止,破坏线程安全的示例 */ public class Demo { public static void main(String[] args) throws InterruptedException { StopThread thread = new StopThread(); thread.start(); // 休眠1秒,确保i变量自增成功 Thread.sleep(1000); // 暂停线程 thread.stop(); // 错误的终止 //thread.interrupt(); // @正确终止 while (thread.isAlive()) { // 确保线程已经终止 } // 输出结果 thread.print(); } }
理想状态:要么自增成功i=1, j=1,要么自增失败i=0, j=0
真正程序执行结果:i=1, j=0
没有保证同步代码块里面数据的一致性,破坏了线程安全
stop方法直接停止线程
正确的线程中止-interrupt
如果目标线程在调用Object class的wait()、wait(long)或wait(long, int)方法、join()、join(long, int)或sleep(long, int)方法时被阻塞,那么Interrupt会生效,该线程的中断状态将被清除,抛出InterruptedException异常。
如果目标线程是被I/O或者NIO中的Channel所阻塞,同样,I/O操作会被中断或者返回特殊异常值。达到终止线程的目的。
如果以上条件都不满足,则会设置此线程的中断状态。
对Demo中的示例,stop()改成interrupt()后,最终输出为"i=1 j=1",数据一致。
正确的线程中止-标志位
/** 通过状态位来判断 */ public class Demo4 extends Thread { public volatile static boolean flag = true; public static void main(String[] args) throws InterruptedException { new Thread(() -> { try { while (flag) { // 判断是否运行 System.out.println("程序运行中"); Thread.sleep(1000L); } } catch (InterruptedException e) { e.printStackTrace(); } }).start(); // 3秒之后,将状态标志改为False,代表不继续运行 Thread.sleep(3000L); flag = false; System.out.println("程序运行结束"); } }
在上方代码逻辑中,增加一个判断,用来控制线程执行的中止。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
快速搭建一个java环境的服务器详解(上云就上阿里云)
一. 服务器的购买 我选择的是阿里云的服务器,百度直接搜索阿里云,然后点击右上角登录,推荐大家用支付宝扫码登录,方便快捷。阿里云官网的东西比较多,登录后我找了很久也没有找到学生服务器在哪里卖,最后在咨询里找到了这个网址,购买的时候需要进行学生认证,按照他的要求一步步来就好,认证大概需要几个小时。如果你不是学生那就直接购买ecs服务器就好,首页就可以看到ecs服务器的购买地址,但是要比学生服务器贵不少。在这里要说一下预装环境的选择,因为大部分服务器都是linux系统,linux中centos的使用又是最多的,所以推荐大家也选择centos系统,然后是应用镜像的选择,应用镜像的作用主要就是帮你预装服务器的环境,比如mysql,apache,tomcat这些,有的还会给你提供管理服务器的面板,方便对服务器的操作。应用镜像可用可不用,如果你只是想快速的配置好服务器,推荐大家安装宝塔linux面板,使用起来很方便,如果你想了解或者已经了解一些linux的使用,就可以忽略应用镜像自己手动配置。如果是用来学习的话地域的选择是无所谓的,可以选择一个离自己近的。 ...
- 下一篇
SpringBoot2.0 整合 QuartJob ,实现定时器实时管理
一、QuartJob简介 1、一句话描述 Quartz是一个完全由java编写的开源作业调度框架,形式简易,功能强大。 2、核心API (1)、Scheduler 代表一个 Quartz 的独立运行容器,Scheduler 将 Trigger 绑定到特定 JobDetail, 这样当 Trigger 触发时, 对应的 Job 就会被调度。 (2)、Trigger 描述 Job 执行的时间触发规则。主要有 SimpleTrigger 和 CronTrigger 两个子类,通过一个 TriggerKey 唯一标识。 (3)、Job 定义一个任务,规定了任务是执行时的行为。JobExecutionContext 提供了调度器的上下文信息,Job 的数据可从 JobDataMap 中获取。 (4)、JobDetail Quartz 在每次执行 Job 时,都重新创建一个 Job 实例,所以它不直接接受一个 Job 的实例,相反它接收一个 Job 实现类。描述 Job 的实现类及其它相关的静态信息,如 Job 名字、描述等。 二、与SpringBoot2.0 整合 1、项目结构 版本描述 spr...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16