JUC(十二)-线程中断相关问题(LockSupport,sleep,InterruptException)

本文详细探讨了Java线程中断时与sleep方法及LockSupport工具类的关系。当线程调用sleep并被中断时,会抛出InterruptedException并重置中断标记位;而被LockSupport.park挂起的线程在被中断后不会抛出异常,但中断标记位变为true。此外,中断后的线程若接着调用sleep,仍会抛出异常并重置中断状态。
摘要由CSDN通过智能技术生成

JUC线程中断相关问题总结

一、 sleep 和线程中断之间的关系和特点

结论

  1. 线程调用 Thread.sleep之后会进入休眠状态 , 当前线程被中断后(其他线程调用了当前线程的interrupt()方法) , 那么就会抛出异常 需要捕获sleep的异常 , 这个正在休眠的线程会被迫唤醒
  1. 休眠的线程被中断后 唤醒后 其中断标记位会重置为false (可通过 thread.isInterrupted() 方法来验证)

测试验证代码如下

public class InterruptDemo {

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

        sleepInterruptThread();

    }

    /**
     * 1. 中断调用了sleep方法的进行休眠的线程
     *
     * 输出结果:
     *
     * 1.SleepInterruptThread|| false
     * ERROR==>抛出异常:sleep interrupted
     * 2.SleepInterruptThread|| false
     * 3.1683772273061|| false
     * 4.1683772275072|| 完成任务!
     *
     * 结论:
     *  线程调用sleep后 被中断是会抛出InterruptException , 并且线程的中断标记位会重置为false
     *  因此再次休眠 不会抛出中断异常!
     *
     */
    private static void sleepInterruptThread() throws InterruptedException {

        Thread t1 = new Thread(() -> {
            System.out.println("1." + Thread.currentThread().getName() + "|| " + Thread.currentThread().isInterrupted());
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                System.out.println("ERROR==>抛出异常:" + e.getMessage());
                System.out.println("2." + Thread.currentThread().getName() + "|| " + Thread.currentThread().isInterrupted());
            }
            System.out.println("3." + System.currentTimeMillis() + "|| " + Thread.currentThread().isInterrupted());

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("4." + System.currentTimeMillis() + "|| 完成任务!");
        },"SleepInterruptThread");

        t1.start();

        Thread.sleep(1000);
        t1.interrupt();
    }


}

二、 LockSupport 和线程中断之间的关系

结论

  1. 被LockSupport.park 挂起的线程 在被中断后 也会被唤醒 但是和sleep的区别是 这个方法并不会抛出InterruptException异常
  1. 中断唤醒之后不会抛出异常 , 但是这个线程的中断标记位变为了true 并不会重置 (可通过 thread.isInterrupted() 方法来验证)

测试验证代码如下

测试LockSupport.park中断后的线程状态 , 还有中断后和sleep方法结合使用

public class LockSupportDemo {


    public static void main(String[] args) throws InterruptedException {
        // 1. 测试LockSupport挂起的线程 被中断是否抛出异常
        lockSupport();
        Thread.sleep(1000);
        System.out.println("=============================================");
        System.out.println("=============================================");
        System.out.println("=============================================");
        // 2. 测试LockSupport中断后和sleep方法一起使用
        lockSupportSleep();
    }

    /**
     * 1. 被LockSupport.park 挂起的线程 调用中断方法后并不会抛出异常 , 但是线程的中断标记位的确变为了true
     *
     * 输出结果:
     *
     * 1.LockSupportThread||false
     * 3.LockSupportThread||true
     * 2.LockSupportThread||true
     *
     * 可以看到通过 LockSupport 挂起的线程在被中断后并不会抛出异常 但是中断标记位是改为了true
     *
     */
    private static void lockSupport() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            System.out.println("1." + Thread.currentThread().getName() + "||" + Thread.currentThread().isInterrupted());
            // 将线程挂起
            LockSupport.park();

            System.out.println("2." + Thread.currentThread().getName() + "||" + Thread.currentThread().isInterrupted());

            // 如果后边跟上 Thread.sleep 则会抛出InterruptException异常 并重置线程中断标记位为false , 看下边 lockSupportSleep

        },"LockSupportThread");

        t1.start();

        Thread.sleep(500);

        t1.interrupt();

        System.out.println("3." + t1.getName() + "||" + t1.isInterrupted());
    }

    /**
     * 2. LockSupport中断线程后 和sleep方法结合使用
     *
     * 输出结果:
     *
     * 1.LockSupportSleepThread||false
     * 2.LockSupportSleepThread||true
     * 抛出异常==》sleep interrupted
     * 3.LockSupportSleepThread||false
     */
    private static void lockSupportSleep() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            System.out.println("1." + Thread.currentThread().getName() + "||" + Thread.currentThread().isInterrupted());
            // 将线程挂起
            LockSupport.park();

            System.out.println("2." + Thread.currentThread().getName() + "||" + Thread.currentThread().isInterrupted());

            // 如果后边跟上 Thread.sleep 则会抛出InterruptException异常 并重置线程中断标记位为false , 看下边 lockSupportSleep
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("抛出异常==》" + e.getMessage());
                System.out.println("3." + Thread.currentThread().getName() + "||" + Thread.currentThread().isInterrupted());
            }
        },"LockSupportSleepThread");

        t1.start();

        Thread.sleep(500);

        t1.interrupt();
    }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值