interrupt方法打断线程demo

1.打断非阻塞状态的线程

package com.demo;

public class InterruputDemo {

    public static void main(String[] args) throws InterruptedException {
        demo1();
    }

    /**
     *1.在main线程中调用子线程的interrupt方法,子线程中无阻塞方法
     */
    private static void demo1() throws InterruptedException {
        //子线程
        Thread t2 = new Thread(() -> {
            int count = 0;
            //开始时,中断标志为false,进入循环
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("子线程运行中。。。" + count++);
                System.out.println("子线程运行中。。。1");
                System.out.println("子线程运行中。。。2");
                System.out.println("子线程运行中。。。3");
                System.out.println("子线程运行中。。。4");
                System.out.println("子线程运行中。。。5");
                System.out.println("子线程运行中。。。6");
            }
            //当main中调用了interrupt,中断标志变为true,退出循环
            System.out.println("子线程中断标志="+Thread.currentThread().isInterrupted());
        });
        t2.start();
        //主线程
        int count = 0;
        while (true) {
            //睡眠1秒,等待子线程进入睡眠
            Thread.sleep(1000);
            t2.interrupt();
            System.out.println("main运行中。。。" + count++);
        }
    }
}

运行结果:

子线程运行中。。。6
子线程运行中。。。7333
子线程运行中。。。1
子线程运行中。。。2
子线程运行中。。。3
子线程运行中。。。4
子线程运行中。。。5
子线程运行中。。。6
子线程运行中。。。7334
子线程运行中。。。1
子线程运行中。。。2
子线程运行中。。。3
子线程运行中。。。4
main运行中。。。0
子线程运行中。。。5
子线程运行中。。。6
子线程中断标志=true
main运行中。。。1
main运行中。。。2
main运行中。。。3
main运行中。。。4
main运行中。。。5
main运行中。。。6
main运行中。。。7

结论:

  1. 调用了另一个线程的interrupt方法后,会将它的中断标志位设置为false(没有抛出InterruptedException 的情况下);

  2. 被打断的线程除了标志位发生变化,没有任何改变。若没有其他操作,将会顺利执行完毕线程中的代码。

2.打断阻塞状态的线程

package com.demo;

public class InterruputDemo {

    public static void main(String[] args) throws InterruptedException {
        demo2();
    }

    /**
     *打断线程的睡眠状态
     */
    public static void demo2() throws InterruptedException {

        Thread t = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    System.out.println("子线程运行中。。。");
                    //睡眠30秒
                    Thread.sleep(30000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    //当另一个线程(main线程)调用了本线程的interrupt方法后,若本线程正在sleep则会抛出InterruptedException异常,否则啥也不会发生;
                    //只有声明了InterruptedException异常的方法才会抛出这个异常;
                    //InterruptedException被抛出后,我们检查当前线程的阻塞状态,发现是false
                    boolean interrupted1 = Thread.currentThread().isInterrupted();//false
                    System.out.println("子线程的中断状态1=" + interrupted1);
                    Thread.currentThread().interrupt();
                    boolean interrupted2 = Thread.currentThread().isInterrupted();//true
                    System.out.println("子线程的中断状态2=" + interrupted2);
                }
            }
        });
        t.start();

        int count = 0;
        while (true) {
            //睡眠1秒,等待子线程进入睡眠
            Thread.sleep(1000);
            t.interrupt();
            System.out.println("main运行中。。。" + count++);
        }
    }
}

运行结果:

子线程运行中。。。
main运行中。。。0
子线程的中断状态1=false
子线程的中断状态2=true
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.demo.InterruputDemo.lambda$demo2$0(InterruputDemo.java:19)
	at java.lang.Thread.run(Thread.java:748)
main运行中。。。1
main运行中。。。2
main运行中。。。3
main运行中。。。4

结论:

  1. 打断阻塞状态sleep中的线程,sleep方法会抛出InterruptedException异常;
  2. 抛出InterruptedException异常时,线程的中断标志会重新设置为false;
  3. 要想通过判断中断标志退出线程循环,需要在catch中再调用一次interrupt将中断标志设置为true。这时线程并不在阻塞状态,不会抛出异常。

总结:

  1. 中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断。
  2. Thread.interrupt()方法不会中断一个正在运行的线程。
  3. 如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该Thread类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个InterruptedException异常。这个时候,我们可以通过捕获InterruptedException异常来终止线程的执行,具体可以通过return等退出或改变共享变量的值使其退出。
  4. synchronized在获锁的过程中是不能被中断的,意思是说如果产生了死锁,则不可能被中断(请参考后面的测试例子)。与synchronized功能相似的reentrantLock.lock()方法也是一样,它也不可中断的,即如果发生死锁,那么reentrantLock.lock()方法无法终止,如果调用时被阻塞,则它一直阻塞到它获取到锁为止。但是如果调用带超时的tryLock方法reentrantLock.tryLock(long timeout, TimeUnit unit),那么如果线程在等待时被中断,将抛出一个InterruptedException异常,这是一个非常有用的特性,因为它允许程序打破死锁。你也可以调用reentrantLock.lockInterruptibly()方法,它就相当于一个超时设为无限的tryLock方法。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值