java线程如何中断?Thread interrupt没有想象那么简单?

引子

本来以为interrupt()后,线程就立刻停止了,其实不是这样的!!!

interrupt()通知线程应该停止

interrupt()是Thread的实例方法,它通过设置线程中断状态,来提示线程应该停止,真正是否停止何时停止取决于程序员;interrupt()时,如果线程在WAITING/TIMED_WAITING状态(执行了wait()、wait(long)、join()、join(long)、sleep(long))则会清除中断状态,抛出InterruptedException,注不要使用stop来中止线程,此方法已不推荐使用,并会带来状态一致性问题。

interrupt()改变状态

Thread a = new Thread(new Runnable() {
            @Override
            public void run() {
                int i=0;
                while(true){

                    System.out.println(Thread.currentThread().isInterrupted()+"--"+(++i));
                }
            }
        });
        a.start();
        a.interrupt();
        System.out.println("线程被中断了");
线程被中断了
true--1
true--2
true--3
true--4
true--5
true--6
true--7
...

可以看到,执行了interrupt()后,线程为中断状态,但线程未停止。
一般的,如果接到线程终止,应该停止,如下


                while(true){
                    if(Thread.currentThread().isInterrupted()){  // 通过判断中止状态来采取操作
                        break;
                    }
                    System.out.println(Thread.currentThread().isInterrupted()+"--"+(++i));
                }
        

输出结果,没有输出数字

线程被中断了

waiting/timed_waiting状态,interrupt()线程抛出异常

线程处在waiting/timed_waiting状态,interrupt()导致目标线程抛出InterruptedException异常,并清除中断状态;

Thread a = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getState()+"-begin-"+Thread.currentThread().isInterrupted()); // 1
                try {
                    Thread.sleep(2000); //7
                } catch (InterruptedException e) {
                    System.out.println(Thread.currentThread().getState()+"-end-"+Thread.currentThread().isInterrupted()); //2
                    e.printStackTrace(System.out);
                }
            }
        });
        a.start(); //3
        System.out.println(a.getState()+"--"+a.isInterrupted()); //4
        a.interrupt(); //5
        System.out.println(a.getState()+"--"+a.isInterrupted()); //6

输出结果有好几种情况,这是因为多线程交替执行导致,包括但不限于以下几种情况


这种情况的执行顺序是,345612


RUNNABLE--false  //
RUNNABLE--true
RUNNABLE-begin-true
RUNNABLE-end-false
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at test.Test$1.run(Test.java:15)
	at java.lang.Thread.run(Thread.java:745)

这种情况的执行顺序是,341562

RUNNABLE--false
RUNNABLE-begin-false
RUNNABLE--true
RUNNABLE-end-false
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at test.Test$1.run(Test.java:15)
	at java.lang.Thread.run(Thread.java:745)

这种情况的执行顺序是,317456,咱们重点解释这种情况,a.start()后,接着执行a线程run方法,1输出false,执行到7,进入timed_waiting状态,线程切换到主线程执行4,输出false,执行5后,线程中断状态为true,继续执行5,输出true,调度器切换到a线程抛出异常清除中断状态,执行2输出false。

RUNNABLE-begin-false
TIMED_WAITING--false
TIMED_WAITING--true
RUNNABLE-end-false
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at test.Test$1.run(Test.java:15)
	at java.lang.Thread.run(Thread.java:745)

interrupt() vs isInterrupted() vs interrupted()

  • public void interrupt()
    • 设置线程状态,如果线程处在WAITING/TIMED_WAITING状态,则抛出InterruptedException,并清除中断状态;
  • public boolean isInterrupted()
    • 获取线程中断状态;
  • public static boolean interrupted()
    • 获取当前线程中断状态,然后清除中断状态,也就是说,如果连续执行两次,第二次为false
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值