Java中的线程中断:interrupt()、interrupted()和isInterrupted

使用interrupt()中断线程

当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。

这里需要注意的是,如果只是单纯的调用interrupt()方法,线程并没有实际被中断,会继续往下执行。

下面一段代码演示了休眠线程的中断:

package com.wrh.threadInterrupt;

public class ThreadInterrupt implements Runnable{

    public static void main(String[] args) {
        //开启一个线程
        ThreadInterrupt runnable=new ThreadInterrupt();
        Thread t=new Thread(runnable);
        t.start();

        try {
            Thread.sleep(5000);//使main线程休息会,让子线程有时间运行会。
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //中断子线程
        System.out.println("main ----即将中断子线程");
        t.interrupt();
        System.out.println("main-----main线程运行结束结束");
    }

    @Override
    public void run() {
        System.out.println("run----子线程正在运行");
        try {
            Thread.sleep(20000);//子线程休息20秒,等待main线程来终端
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            System.out.println("run-----子线程在休息的时候被中断");
            return;//如果没有return,则即使线程中断也不会立即返回,他还会继续运行下面的代码
        }

        System.out.println("run-------子线程运行结束");

    }

}

上面的逻辑很清楚,这里就不在解释。
运行结果如下

run—-子线程正在运行
main —-即将中断子线程
main—–main线程运行结束结束
run—–子线程在休息的时候被中断

这里要说明的是:由于不确定的线程规划,程序中后面两条语句的输出顺序可能相反。

待决中断

在上面的例子中,线程在执行sleep()方法休眠时被其它线程中断,它会相当友好地终止线程,并抛出InterruptedException异常。另外一种情况,如果线程在调用sleep()方法被中断,那么该中断称为待决中断,它会在刚调用sleep()方法时,立即抛出InterruptedException异常。

package com.wrh.threadInterrupt;

public class PendingInterrupt {
    private static boolean flag;
    public static void main(String[] args) {
        flag=true;
        if(flag){
            Thread.currentThread().interrupt();//中断当前线程
        }
        long curTime=System.currentTimeMillis();
        try {//当前线程休眠20秒
            System.out.println("当前线程即将sleep的前一条语句");
            Thread.sleep(20000);
            System.out.println("程序没有被中断");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            System.out.println("程序被中断");
        }

        System.out.println("程序运行的时间:"+(System.currentTimeMillis()-curTime));

    }

}

/*
 * 当falg=false时
 * 输出:   当前线程即将sleep的前一条语句
 *      程序没有被中断
        程序运行的时间:20000
    当flag=true时
    输出:当前线程即将sleep的前一条语句
        程序被中断
        程序运行的时间:0
 * */

有的人可能会有这样的译文:main线程中断了,它怎么还在继续运行呀?
原因是:在catch块中没有return,因此,只用interrupt()是无法立即中断线程的,它还会继续往下面运行。

Thread.interrupted()来判断当前线程是否中断

可以使用Thread.interrupted()方法来检查当前线程的是否中断(并隐式重置为false)。又由于它是静态方法,因此不能在特定的线程上使用,而只能报告调用它的线程的中断状态,如果线程被中断,而且中断状态尚不清楚,那么,这个方法返回true。与isInterrupted()不同,它将自动重置中断状态为false,第二次调用Thread.interrupted()方法,总是返回false,除非中断了线程。

package com.wrh.threadInterrupt;

public class ThreadInterrupted {

    public static void main(String[] args) {
        System.out.println("A点:Thread.interruped()的结果为"+Thread.interrupted());
        //线程中断
        Thread.currentThread().interrupt();
        System.out.println("B点:Thread.interruped()的结果为"+Thread.interrupted());

        System.out.println("C点:Thread.interruped()的结果为"+Thread.interrupted());
    }

}
/*
 * 运行结果:
 *  A点:Thread.interruped()的结果为false
    B点:Thread.interruped()的结果为true
    C点:Thread.interruped()的结果为false
 * */

isInterrupted()来判断线程是否被中断

package com.wrh.threadInterrupt;
//isInterrupt()方法的用法
public class ThreadIsInterrupt {

    public static void main(String[] args) {
        System.out.println("A点: Thread.currentThread().isInterrupted()="+Thread.currentThread().isInterrupted());
        Thread.currentThread().interrupt();;//线程中断
        System.out.println("B点: Thread.currentThread().isInterrupted()="+Thread.currentThread().isInterrupted());
        System.out.println("C点: Thread.currentThread().isInterrupted()="+Thread.currentThread().isInterrupted());
    }

}

运行结果

A点: Thread.currentThread().isInterrupted()=false
B点: Thread.currentThread().isInterrupted()=true
C点: Thread.currentThread().isInterrupted()=true

从结果可以看出,当线程被中断后,Thread.currentThread().isInterrupted()的结果就被一直是ture,与interrupted()不一样,不会重置会false;这一点要区分开

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值