java线程中断
public void Thread.interrupt() // 无返回值
public boolean Thread.isInterrupted() // 有返回值
public static boolean Thread.interrupted() // 静态,有返回值
使用interrupt()中断线程
当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。这里需要注意的是,如果只是单纯的调用interrupt()方法,线程并没有实际被中断,会继续往下执行。
public class InterruptTest {
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread("MyThread");
t.start();
Thread.sleep(100);// 睡眠100毫秒
t.interrupt();// 中断t线程
}
}
class MyThread extends Thread {
int i = 0;
public MyThread(String name) {
super(name);
}
public void run() {
while(true) {// 死循环,等待被中断
System.out.println(getName() + getId() + "执行了" + ++i + "次");
}
}
}
运行后,我们发现,线程t一直在执行,没有被中断,原来interrupt()是骗人的,汗!其实interrupt()方法并不是中断线程的执行,而是为调用该方法的线程对象打上一个标记,设置其中断状态为true,通过isInterrupted()方法可以得到这个线程状态,我们将上面的程序做一个小改动:
public class InterruptTest {
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread("MyThread");
t.start();
Thread.sleep(100);// 睡眠100毫秒
t.interrupt();// 中断t线程
}
}
class MyThread extends Thread {
int i = 0;
public MyThread(String name) {
super(name);
}
public void run() {
while(!isInterrupted()) {// 当前线程没有被中断,则执行
System.out.println(getName() + getId() + "执行了" + ++i + "次");
}
}
}
这样的话,线程被顺利的中断执行了。很多人实现一个线程类时,都会再加一个flag标记,以便控制线程停止执行,其实完全没必要,通过线程自身的中断状态,就可以完美实现该功能。如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。 我们可以捕获该异常,并且做一些处理。另外,Thread.interrupted()方法是一个静态方法,它是判断当前线程的中断状态,需要注意的是,线程的中断状态会由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。
下面一段代码演示了休眠线程的中断:
public class SleepInterrupt extends Object implements Runnable{
public void run(){
try{
System.out.println("in run() - about to sleep for 20 seconds");
Thread.sleep(20000);
System.out.println("in run() - woke up");
}catch(InterruptedException e){
System.out.println("in run() - interrupted while sleeping");
//处理完中断异常后,返回到run()方法人口,
//如果没有return,线程不会实际被中断,它会继续打印下面的信息
return;
}
System.out.println("in run() - leaving normally");
} public static void main(String[] args) {
SleepInterrupt si = new SleepInterrupt();
Thread t = new Thread(si);
t.start();
//主线程休眠2秒,从而确保刚才启动的线程有机会执行一段时间
try {
Thread.sleep(2000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("in main() - interrupting other thread");
//中断线程t
t.interrupt();
System.out.println("in main() - leaving");
}
}
运行结果如下:
待决中断
在上面的例子中,sleep()方法的实现检查到休眠线程被中断,它会相当友好地终止线程,并抛出InterruptedException异常。另外一种情况,如果线程在调用sleep()方法前被中断,那么该中断称为待决中断,它会在刚调用sleep()方法时,立即抛出InterruptedException异常。
下面的代码演示了待决中断:
public class PendingInterrupt extends Object {
public static void main(String[] args){
//如果输入了参数,则在mian线程中中断当前线程(亦即main线程)
if( args.length > 0 ){
Thread.currentThread().interrupt();
}
//获取当前时间
long startTime = System.currentTimeMillis();
try{
Thread.sleep(2000);
System.out.println("was NOT interrupted");
}catch(InterruptedException x){
System.out.println("was interrupted");
}
//计算中间代码执行的时间
System.out.println("elapsedTime=" + ( System.currentTimeMillis() - startTime));
}
}
如果PendingInterrupt不带任何命令行参数,那么线程不会被中断,最终输出的时间差距应该在2000附近(具体时间由系统决定,不精确),如果PendingInterrupt带有命令行参数,则调用中断当前线程的代码,但main线程仍然运行,最终输出的时间差距应该远小于2000,因为线程尚未休眠,便被中断,因此,一旦调用sleep()方法,会立即打印出catch块中的信息。执行结果如下:
使用isInterrupted()方法判断中断状态
运行结果如下:
使用Thread.interrupted()方法判断中断状态
可以使用Thread.interrupted()方法来检查当前线程的中断状态(并隐式重置为false)。又由于它是静态方法,因此不能在特定的线程上使用,而只能报告调用它的线程的中断状态,如果线程被中断,而且中断状态尚不清楚,那么,这个方法返回true。与isInterrupted()不同,它将自动重置中断状态为false,第二次调用Thread.interrupted()方法,总是返回false,除非中断了线程。
如下代码演示了Thread.interrupted()方法的使用:
public class InterruptReset extends Object {
public static void main(String[] args) {
System.out.println(
"Point X: Thread.interrupted()=" + Thread.interrupted());
Thread.currentThread().interrupt();
System.out.println(
"Point Y: Thread.interrupted()=" + Thread.interrupted());
System.out.println(
"Point Z: Thread.interrupted()=" + Thread.interrupted());
}
}
补充
java线程中断的更多相关文章
- 一文搞懂 Java 线程中断
在之前的一文<如何"优雅"地终止一个线程>中详细说明了 stop 终止线程的坏处及如何优雅地终止线程,那么还有别的可以终止线程的方法吗?答案是肯定的,它就是我们今天要分 ...
- java线程中断和终止线程运行
ava中启动一个线程很容易,通常情况下我们都是等到任务运行结束后让线程自行停止.但有时需要在任务正在运行时取消他们,使得线程快速结束.对此Java并没有提供任何机制.但是我们可以通过Java提供的线程 ...
- Java线程中断的本质深入理解(转)
一.Java中断的现象 首先,看看Thread类里的几个方法: public static boolean interrupted 测试当前线程是否已经中断.线程的中断状态 由该方法清除.换句话说,如 ...
- java线程中断的办法
目录 中断线程相关的方法 中断线程 for循环标记退出 阻塞的退出线程 使用stop()方法停止线程 中断线程相关的方法 中断线程有一些相应的方法,这里列出来一下. 注意,如果是Thread.meth ...
- Java线程中断理解(interrupte)
Java线程之中,一个线程的生命周期分为:初始.就绪.运行.阻塞以及结束.当然,其中也可以有四种状态,初始.就绪.运行以及结束. 一般而言,可能有三种原因引起阻塞:等待阻塞.同步阻塞以及其他阻塞(睡眠 ...
- Java线程中断的本质深入理解
Java的中断是一种协作机制.也就是说调用线程对象的interrupt方法并不一定就中断了正在运行的线程,它只是要求线程自己在合适的时机中断自己. 一.Java中断的现象 首先,看看Thread类里的 ...
- java线程中断[interrupt()函数] (转载)
一个正常的线程中断: 从运行到真正的结束,应该有三个阶段: 正常运行. 处理结束前的工作,也就是准备结束. 结束退出. Java曾经提供过抢占式限制中断,但问题多多,例如的Thread.stop.另一 ...
- java线程中断2
一个线程在未正常结束之前, 被强制终止是很危险的事情. 因为它可能带来完全预料不到的严重后果. 所以你看到Thread.suspend, Thread.stop等方法都被Deprecated了.那么不 ...
- lesson6:java线程中断
正常的情况下,业务系统都不会去中断它的线程,但是由于一些特殊情况的发生,线程已经不能正常结束了,并且此类线程已经影响到业务系统提供服务的能力,如果系统设计的健壮,便会通过监控线程去主动的中断此类线程. ...
随机推荐
- [SQL Server] 常用sql脚本
1.添加表 GO IF NOT EXISTS(SELECT * FROM sys.tables WHERE name='table_name') BEGIN CREATE TABLE [dbo].[t ...
- c/c++排坑(5) -- c语言中的申明
C语言的申明总是令人头大,对于这块内容也一直让我头疼.希望通过这篇博客能够稍微梳理一下.材料和例子来源于<C专家编程> 一.C语言的申明的优先级规则 先来个例子,看看下面这行C代码到底是个 ...
- Books Queries (codeforces 1066C)
模拟题 开一个容器进行模拟即可,注意容器设置初始大小不然容易re.设置两个指针l,r.把容器当作桶,每一个桶都有一个编号表示位置,左边进入那么就是编号为l,右边一样.然后l--或者r++,l=r=0的 ...
- Linux下源码安装Peach-2.3.8教程
在peach文件夹下运行 python peach.py ./samples/HelloWorld.xml 提示先安装4Suite-XML. 根据提示在dependences文件夹下安装,出现两次错误 ...
- C#关键字详解第一节
abstract:抽象类: 他表达对问题或者实际中的事物,对象等所设计出的抽象概念,比如一个灵感.生物等,这些都是抽像, 但是他们往往也有具体的指向,比如生物圈有人类,猴子,老虎等等,老虎和人类是实际 ...
- Java基础学习总结(73)——Java最新面试题汇总
1.super()与this()的区别? this():当前类的对象,super父类对象. super():在子类访问父类的成员和行为,必须受类继承规则的约束 而this他代表当前对象,当然所有的资源 ...
- springCloud学习-分布式配置中心(Spring Cloud Config)
1.简介 Spring Cloud Config :分布式配置中心,方便服务配置文件统一管理,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中.在spring cloud co ...
- hdu_1060_Leftmost Digit_201311071827-2
Leftmost Digit Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
- android获取当前软件版本号号和版本号名称
<span style="font-size:18px;">/** * 获取本地软件版本号 */ public static int getLocalVersion(C ...
- hdu5242 上海邀请赛 优先队列+贪心
题意是给你一棵树 n个点 n-1条边 起点是1 每一个点都有权值 每次能从根节点走到叶子节点 经行k次游戏 每次都是从1開始 拿过的点的权值不能拿第二次 问最大权值和. 開 ...