java基础知识回顾之java Thread类学习(十二)-- 线程中断
官方文档翻译:
如果本线程是处于阻塞状态:调用线程的wait(), wait(long)或wait(long, int)会让它进入等待(阻塞)状态,或者调用线程的join(), join(long),
join(long, int), sleep(long), sleep(long, int)也会让它进入阻塞状态。若线程在阻塞状态时,调用了它的interrupt()方法,那么
它的“中断状态”会被清除并且会收到一个InterruptedException异常。例如,线程通过wait()进入阻塞状态,此时通过interrupt()中断该线程;
调用interrupt()会立即将线程的中断标记设为“true”,但是由于线程处于阻塞状态,所以该“中断标记”会立即被清除为“false”,同时,会产生一个InterruptedException的异常。
如果线程被阻塞在一个Selector选择器中,那么通过interrupt()中断它时;线程的中断标记会被设置为true,并且它会立即从选择操作中返回。
如果不属于前面所说的情况,那么通过interrupt()中断线程时,它的中断标记会被设置为“true”。中断一个“已终止的线程”不会产生任何操作。
线程处于“阻塞状态”和“运行状态”的终止方式如下:
(1)使用isInterrupted判断,使用interrupt中断
@Override
public void run() {
try {
// 1. isInterrupted()保证,只要中断标记为true就终止线程。
while (!isInterrupted()) {
// 执行任务...
}
} catch (InterruptedException ie) {
// 2. InterruptedException异常保证,当InterruptedException异常产生时,线程被终止。
}
}
例子1:
package concurrentMy.interrupts; /**
*
* (interrupt()常常被用来终止“阻塞状态”线程。)
*
* <p>
* 修改历史: <br>
* 修改日期 修改人员 版本 修改内容<br>
* -------------------------------------------------<br>
* 2016年11月3日 下午2:56:44 user 1.0 初始化创建<br>
* </p>
*
* @author Peng.Li
* @version 1.0
* @since JDK1.7
* 运行结果: A线程的状态: (NEW) is new
A线程的状态: (RUNNABLE) is start
A线程的状态: (RUNNABLE) loop 1
A线程的状态: (RUNNABLE) loop 2
A线程的状态: (TIMED_WAITING) is interrupted
A线程的状态: (RUNNABLE) catch InterruptedException.
A线程的状态: (TERMINATED) is interrupted now 结果说明:1.主线程通过 new ThreadMy("A")创建线程t1,之后之后通过t1.start()启动线程A。
2.线程A启动之后,会不断的检查它的中断标识,如果中断标识为false,则休眠100ms
3.t1休眠之后,会切换到主线程main,主线程再次运行,会执行t1.interrupt();中断A线程,
A收到中断指令后,将A线程的中断标识设置成“false”,而且会抛出InterruptedException异常
*
*/ class ThreadMy extends Thread { public ThreadMy(String name) {
super(name);
} @Override
public void run() {
int i = 0;
try {
//1. isInterrupted()保证,只要中断标记为true就终止线程。
while (!isInterrupted()) {
//线程A休眠,进入阻塞状态
Thread.sleep(100);
i++;
// 返回当前线程的状态
System.out.println(Thread.currentThread().getName() + "线程的状态: (" + this.getState() + ") loop " + i);
} } catch (InterruptedException e) {
// 2. InterruptedException异常保证,当InterruptedException异常产生时,线程被终止。
// TODO: handle exception
System.out.println(Thread.currentThread().getName() + "线程的状态: (" + this.getState() + ") catch InterruptedException.");
} }
} public class Demo1_interrupt {
public static void main(String[] args) {
try {
// 新建线程A
ThreadMy t1 = new ThreadMy("A");
System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is new");
// 启动线程A
t1.start();
System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is start");
// 主线程休眠300毫秒,然后main线程给t1发送指令
Thread.sleep(300);
t1.interrupt(); System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is interrupted"); // 主线程再休眠300ms,查看A线程的状态
Thread.sleep(300);
System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is interrupted now");
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
(2)安全的终止线程,使用volatile boolean变量。
package concurrentMy.interrupts; /**
*
*
* <p>
* 修改历史: <br>
* 修改日期 修改人员 版本 修改内容<br>
* -------------------------------------------------<br>
* 2016年11月3日 下午2:56:44 user 1.0 初始化创建<br>
* </p>
*
* @author Peng.Li
* @version 1.0
* @since JDK1.7
* 安全的终止线程,使用volatile boolean变量。 运行结果: A线程的状态: (NEW) is new
A线程的状态: (RUNNABLE) is start
A线程的状态: (RUNNABLE) loop 1
A线程的状态: (RUNNABLE) loop 2
A线程的状态: (TIMED_WAITING) is interrupted
A线程的状态: (RUNNABLE) loop 3
count3
A线程的状态: (TERMINATED) is interrupted now 结果说明:1.主线程通过 new ThreadMy("A")创建线程t1,之后之后通过t1.start()启动线程A。
2.线程A启动之后,会不断的检查它的中断标识,如果中断标识为true,则休眠100ms
3.t1休眠之后,会切换到主线程main,主线程再次运行,会执行t1.cancel();中断A线程,
A收到中断指令后,将A线程的中断标识设置成“false”,清除中断标识,而且会抛出InterruptedException异常
*
*
*
*/ class ThreadMy1 extends Thread { // volatile的应用,保证线程之间对on标识的可见性,一个线程(主线程)改了标识,
// 即调用A线程的cancel方法取消或者停止了任务(A线程的执行,则立即对这个线程(A线程)可见
private volatile boolean on = true; public ThreadMy1(String name) {
super(name);
} /**
*
* (// 通过on 变量来控制是否需要停止任务并且终止任务)
*
*/
public void cancel() {
on = false;
} @Override
public void run() {
int i = 0;
try {
// on = false 的时候中断线程
while (on /* && !isInterrupted() */) {
// 线程A休眠,进入阻塞状态
Thread.sleep(100);
i++;
// 返回当前线程的状态
System.out.println(Thread.currentThread().getName() + "线程的状态: (" + this.getState() + ") loop " + i);
}
System.out.println("count" + i);
} catch (InterruptedException e) {
// 2. InterruptedException异常保证,当InterruptedException异常产生时,线程被终止,这个地方加一些日志操作
// TODO: handle exception
System.out.println(Thread.currentThread().getName() + "线程的状态: (" + this.getState() + ") catch InterruptedException.");
} }
} public class Demo2_interrupt {
public static void main(String[] args) {
try {
// 新建线程A
ThreadMy1 t1 = new ThreadMy1("A");
System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is new");
// 启动线程A
t1.start();
System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is start");
// 主线程休眠300毫秒,然后main线程给t1发送指令
Thread.sleep(300);
// 中断线程
t1.cancel();
System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is interrupted"); // 主线程再休眠300ms,查看A线程的状态
Thread.sleep(300);
System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is interrupted now");
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
java基础知识回顾之java Thread类学习(十二)-- 线程中断的更多相关文章
- java基础知识回顾之---java String final类普通方法
辞职了,最近一段时间在找工作,把在大二的时候学习java基础知识回顾下,拿出来跟大家分享,如果有问题,欢迎大家的指正. /* * 按照面向对象的思想对字符串进行功能分类. * ...
- java基础知识回顾之java Thread类学习(三)--java线程实现常见的两种方式实现好处:
总结:实现Runnable接口比继承Thread类更有优势: 1.因为java只能单继承,实现Runnable接口可以避免单继承的局限性 2.继承Thread类,多个线程不能处理或者共享同一个资源,但 ...
- java基础知识回顾之java Thread类学习(十)--线程的状态以及转化使用的方法介绍
线程的概述: 线程是程序的多个执行路径,执行调度的单位,依托于进程存在.线程不仅可以共享进程的内存,而且还拥有一个属于自己的内存空间,这段内存空间叫做线程栈,是建立线程的时候由系 ...
- java基础知识回顾之java Thread类--java线程实现常见的两种方式实现Runnable接口(二)
创建线程的第二中方式: /** * 步骤: 1定义类实现Runnable接口 2.实现Runnable接口中的run方法. 3.通过Thread类建立线程对象,并将Run ...
- java基础知识回顾之java集合类-Properties集合
/** java.lang.Object |--java.util.Dictionary<K,V> |--java.util.Hashtable<Object,Obje ...
- java基础知识回顾之java Thread类学习(八)--java.util.concurrent.locks(JDK1.5)与synchronized异同讲解
看API文档介绍几个方法: JDK1.5中提供了多线程的升级解决方案: 特点: 1.将同步synchronized显示的替换成Lock 2.接口Conditio ...
- java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)
*java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时 ...
- java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)
上一节售票系统中我们发现,打印出了错票,0,-1,出现了多线程安全问题.我们分析为什么会发生多线程安全问题? 看下面线程的主要代码: @Override public void run() { // ...
- java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)
1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以 ...
- java基础知识回顾之java Thread类学习(六)--java多线程同步函数用的锁
1.验证同步函数使用的锁----普通方法使用的锁 思路:创建两个线程,同时操作同一个资源,还是用卖票的例子来验证.创建好两个线程t1,t2,t1线程走同步代码块操作tickets,t2,线程走同步函数 ...
随机推荐
- ECSHOP验证码背景图修改教程
ECSHOP验证码背景图修改教程 ECSHOP教程/ ecshop教程网(www.ecshop119.com) 2013-11-18 ECSHOP验证码背景图修改教程: ECSHOP前后台的某些地 ...
- iptables 工具
iptables 工具 参考文档: https://www.frozentux.net/iptables-tutorial/cn/iptables-tutorial-cn-1.1.19.html ...
- php 单态设计模式
单态设计模式通常包含以下三点: · 一个私有的 构造方法:(确保用户无法通过创建对象对其进行实例化) · 一个公有的 静态的 方法:(负责对其本身进行实例化) · 一个私有的 静态的 属性:(用于保存 ...
- 新浪微博客户端(5)-自定义UISearchBar
iOS自带的UISearchBar有很多限制,我们可以使用UITextField做出一个类似于SearchBar的效果. //===================================== ...
- (7)UI(基础对象)
1.地图控件: 地图控件可支持导入Tiled地图编辑器导出的tmx格式文件,地图是制作游戏关卡地形图的控件,对于即时战略类型游戏的制作,为了使玩家流畅的切换游戏画面,经常会使用超过屏幕尺寸的地图. ...
- Microsoft.ReportViewer.WebForms, Version=10.0.0.0的报错问题,解决方案
未能加载文件或程序集,或者web.config报错! 已解决:直接找到(默认在 路径/Microsoft Visual Studio 8/ReportViewer).把里面的3个DLL传上去就OK了! ...
- [Effective JavaScript 笔记] 第8条:尽量少用全局对象
初学者容易使用全局变量的原因 创建全局变量毫不费力,不需要任何形式的声明(只要在非函数里用var 你就可以得到一个全局变量) 写得代码简单,不涉及到大的项目或配合(写hello world是不会有什么 ...
- ruby的in?方法
(文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) $ irbirb(main):001:0> a = 1=> 1irb(main):002 ...
- 新的开始---cocos2d
今天是一个新的开始,cocos2d的环境搭配好了,并且打包案桌apk的环境也搭配好了,安卓的这个搭配环境还是出了一点问题,前面弄了两个晚上(11-12.30)没弄出来,中间好几天都没有去弄,今天光棍节 ...
- Nmap备忘单:从探索到漏洞利用(Part 4)
这是我们的Nmap备忘单的第四部分(Part 1. Part 2. Part 3).本文中我们将讨论更多东西关于扫描防火墙,IDS / IPS 逃逸,Web服务器渗透测试等.在此之前,我们应该了解一下 ...