jdk1.8之线程中断
在Core Java中有这样一句话:"没有任何语言方面的需求要求一个被中断的程序应该终止。中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断 "
线程中断不会使线程立即退出,而是给线程发送一个通知,告知目标线程有人希望你退出。至于目标线程接收到通知后如何处理,则完全由目标线程自行决定。
线程中断有关的三个方法
- void Thread.interrupt();//中断线程
- boolean Thread.isInterrupted()//判断是否中断
- static boolean Thread.interrupted()//判断是否中断,并清除当前中断状态
- Thread.interrupt()方法是一个实例方法,它通知目标线程中断,也就是设置中断标志位。中断标志位表示当前线程已经被中断了。
- Thread.isInterrupted()方法也是实例方法,它判断当前线程是否有被中断(通过检查中断标志位)。
静态方法Thread.interrupted()也是用来判断当前线程的中断状态,但同时会清除当前线程的中断标志位状态。
运行中的线程不会因为interrupt()而中断,因为它仅仅是一个信号(status)
public static void main(String[] intsmaze) throws InterruptedException {
Thread t1=new Thread()
{
public void run()
{
while(true){ }
}
};
t1.start();
Thread.sleep(2000);
t1.interrupt();
}
这个程序虽然对t1进程了中断,但是在t1中并没有中断处理的逻辑,因此即使t1线程被置上了中断状态,但是这个中断不会发生任何作用。
如果希望t1在中断后退出,必须为他增加相应的中断处理代码,如下
public static void main(String[] intsmaze) throws InterruptedException {
Thread t1=new Thread()
{
public void run()
{
while(true)
{
if(Thread.currentThread().isInterrupted())//判断当前线程是否中断。
{
System.out.println("intsmaze Interrupt");
break;
}
}
}
};
t1.start();
Thread.sleep(2000);
t1.interrupt();
}
等待中的线程(wait(long),sleep(long),join(long)收到中断信号会抛出InterruptedException
public static native void sleep(long millis) throws InterruptedException;会抛出一个中断异常。当线程在休眠sleep时,如果被中断就会产生该异常,此时它会清楚中断标志,如果不加处理,那么在下一次循环开始时,就无法捕获这个中断。
如果注释掉catch中的Thread.currentThread().interrupt();我们可以发现,程序一直运行,线程没有停止;反之放开该注释,则发现程序运行结束了。
public static void main(String[] intsmaze) throws InterruptedException {
Thread t1=new Thread()
{
public void run()
{
while(true)
{
if(Thread.currentThread().isInterrupted())
{
System.out.println("intsmaze Interrupt");
break;
}
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
System.out.println("Interrupt when intsmaze sleep");
Thread.currentThread().interrupt();//设置中断状态
}
}
}
};
t1.start();
Thread.sleep(2000);
t1.interrupt();
}
BLOCKED
如果线程在等待锁,对线程对象调用interrupt()只是会设置线程的中断标志位,线程依然会处于BLOCKED状态,也就是说,interrupt()并不能使一个在等待锁的线程真正”中断”。通过前面的代码可以看到,中断是通过循环不判进行Thread.currentThread().isInterrupted()判断的。
在使用synchronized关键字获取锁的过程中不响应中断请求,这是synchronized的局限性。如果想在等待获取锁的过程中能响应中断,应该使用显式锁,Lock接口,它支持以响应中断的方式获取锁。
NEW/TERMINATE
如果线程尚未启动(NEW),或者已经结束(TERMINATED),则调用interrupt()对它没有任何效果,中断标志位也不会被设置。比如说,以下代码的输出都是false。
IO操作
如果线程在等待IO操作,尤其是网络IO,则会有一些特殊的处理。
如果IO通道是可中断的,即实现了InterruptibleChannel接口,则线程的中断标志位会被设置,同时,线程会收到异常ClosedByInterruptException。
如果线程阻塞于Selector调用,则线程的中断标志位会被设置,同时,阻塞的调用会立即返回。
我们重点介绍另一种情况,InputStream的read调用,该操作是不可中断的,如果流中没有数据,read会阻塞 (但线程状态依然是RUNNABLE),且不响应interrupt(),与synchronized类似,调用interrupt()只会设置线程的中断标志,而不会真正”中断”它,我们看段代码。
public class InterruptReadDemo {
private static class A extends Thread {
@Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
try {
System.out.println(System.in.read());
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("exit");
}
}
public static void main(String[] args) throws InterruptedException {
A t = new A();
t.start();
Thread.sleep(100);
t.interrupt();
}
}
线程t启动后调用System.in.read()从标准输入读入一个字符,不要输入任何字符,我们会看到,调用interrupt()不会中断read(),线程会一直运行。
拿两年前的笔记出来冒个泡
jdk1.8之线程中断的更多相关文章
- GDB 多线程调试:只停止断点的线程,其他线程任然执行; 或只运行某些线程 其他线程中断
多线程调试之痛 调试器(如VS2008和老版GDB)往往只支持all-stop模式,调试多线程程序时,如果某个线程断在一个断点上,你的调试器会让整个程序freeze,直到你continue这个线程,程 ...
- java并发编程(二)线程中断
参考:http://blog.csdn.net/ns_code/article/details/17091267 使用interrupt()中断线程 当一个线程运行时,另一个线程可以调用对应的Thre ...
- java 线程的终止与线程中断
关于线程终止: 1.一般来讲线程在执行完毕后就会进入死亡状态,那该线程自然就终止了. 2.一些服务端的程序,可能在业务上需要,常驻系统.它本身是一个无穷的循环,用于提供服务.那对于这种线程我们该如何结 ...
- java线程中断和终止线程运行
ava中启动一个线程很容易,通常情况下我们都是等到任务运行结束后让线程自行停止.但有时需要在任务正在运行时取消他们,使得线程快速结束.对此Java并没有提供任何机制.但是我们可以通过Java提供的线程 ...
- Java线程中断的本质深入理解(转)
一.Java中断的现象 首先,看看Thread类里的几个方法: public static boolean interrupted 测试当前线程是否已经中断.线程的中断状态 由该方法清除.换句话说,如 ...
- Java并发编程(2):线程中断(含代码)
使用interrupt()中断线程 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回.这 ...
- 转:【Java并发编程】之二:线程中断(含代码)
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17091267 使用interrupt()中断线程 当一个线程运行时,另一个线程可以调用对应 ...
- Java并发之线程中断
前面的几篇文章主要介绍了线程的一些最基本的概念,包括线程的间的冲突及其解决办法,以及线程间的协作机制.本篇主要来学习下Java中对线程中断机制的实现.在我们的程序中经常会有一些不达到目的不会退出的线程 ...
- 《Java并发编程》之线程中断与终止线程运行
Java中启动一个线程很容易,通常情况下我们都是等到任务运行结束后让线程自行停止.但有时需要在任务正在运行时取消他们,使得线程快速结束.对此Java并没有提供任何机制.但是我们可以通过Java提供的线 ...
随机推荐
- 如何设置访问内网web项目
1.若我的项目搭建在一个linux虚拟机上 2.在内网的一台电脑做以下配置 3.测试访问 ******************************************************* ...
- mssql instead of 触发器应用一-创建只读视图(view)的方法
转自: http://www.maomao365.com/?p=4906 <span style="color:white;background-color:blue;font-wei ...
- STL之迭代器(iterator)
1 头文件 所有容器有含有其各自的迭代器型别(iterator types),所以当你使用一般的容器迭代器时,并不需要含入专门的头文件.不过有几种特别的迭代器,例如逆向迭代器,被定义于<iter ...
- Android 5.0 版本 USB 调试模式打开方法
Android 4.2 版本 USB 调试模式打开方法 1. 进入“设置”页面,点击“关于平板电脑”.见下图红色方框. 2. 疯狂点击“版本号”,见下图红色方框,直到出现“您现在处于开发者模式!” ...
- c/c++ 类成员变量,成员函数的存储方式,以及this指针在c++中的作用
c/c++ 类成员变量,成员函数的存储方式,以及this指针在c++中的作用 c++不会像上图那样为每一个对象的成员变量和成员函数开辟内存空间, 而是像下图那样,只为每一个对象的成员变量开辟空间.成员 ...
- UIWebView的高度不对问题
一般情况,在- (void)webViewDidFinishLoad:(UIWebView *) webView方法里添加如下代码: CGSize actualSize = [webView size ...
- 【爬坑】远程连接 MySQL 失败
问题描述 远程连接 MySQL 服务器失败 报以下错误 host 192.168.23.1 is not allowed to connect to mysql server 解决方案 在服务器端打开 ...
- 【算法】LeetCode算法题-Reverse Integer
这是悦乐书的第143次更新,第145篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第2题(顺位题号是7),给定32位有符号整数,然后将其反转输出.例如: 输入: 123 ...
- June 11. 2018 Week 24th, Monday
Love is the beauty of the soul. 爱是灵魂之美. From Saint Augustine. The complete version of this quote goe ...
- spark SQL读取ORC文件从Driver启动到开始执行Task(或stage)间隔时间太长(计算Partition时间太长)且产出orc单个文件中stripe个数太多问题解决方案
1.背景: 控制上游文件个数每天7000个,每个文件大小小于256M,50亿条+,orc格式.查看每个文件的stripe个数,500个左右,查询命令:hdfs fsck viewfs://hadoop ...