线程知识学习三(线程的“打断”)

线程知识学习三(线程的“打断”)

interrupt的三个方法

1、interrupt():打断某个线程(设置线程中断标志位)
2、isInterrupted():查询某个线程是否被打断过(查询中断标志位)
3、static interrupted():查询当前线程是否被打断过,并重置打断标志

public class Interrupt_and_isInterrupted {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            for (; ; ) {
            //此处查询标志位是否已经被打断过
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("Thread is interrupted!");
                    System.out.println(Thread.currentThread().isInterrupted());
                    break;
                }
            }
        });

        t.start();

        SleepHelper.sleepSeconds(2);
		//此处设置标志位
        t.interrupt();
    }
}

运行结果如下:
在这里插入图片描述
Interrupt and Interrupted:

public class Interrupt_and_interrupted {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            for (; ; ) {
            //查询标志位 true代表已打断
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println(Thread.currentThread().isInterrupted());
                    break;
                }
            }
            for (; ; ) {
                //判断并重置标志位
                if (Thread.interrupted()) {
                    System.out.println("Thread is interrupted!");
                    System.out.println(Thread.interrupted());
                    //这里输出标志位为false代表重置标志位
                }
            }
        });

        t.start();

        SleepHelper.sleepSeconds(2);
		//设置标志位
        t.interrupt();
    }
}

输出结果如下:
在这里插入图片描述
线程执行sleep、wait、join方法时,如果线程被打断都会抛出一个interruptedException,Java会默认重置标志位(因为此处别人可能再次调用interrupt方法,这个打断的状态也需要被捕获到),然后再做后续业务处理。
interrupt and sleep:

public class Interrupt_and_sleep {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                System.out.println("Thread is interrupted!");
                System.out.println(Thread.currentThread().isInterrupted());
            }
        });

        t.start();

        SleepHelper.sleepSeconds(5);

        t.interrupt();
    }
}

运行结果如下:
在这里插入图片描述
同理wait方法和join方法也是这样。

public class Interrupt_and_sync {

    private static Object o = new Object();

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            synchronized (o) {
                SleepHelper.sleepSeconds(10);
            }
        });

        t1.start();

        SleepHelper.sleepSeconds(1);

        Thread t2 = new Thread(() -> {
            synchronized (o) {

            }
            System.out.println("t2 end!");
        });

        t2.start();

        SleepHelper.sleepSeconds(1);

        t2.interrupt();
    }
}

如上程序是线程一通过synchronized获得锁,并且拿到这个锁10s,然后启动线程二启动去等待获得被线程一拿到的锁,在这期间执行线程二的打断方法,检验打断线程是否会影响锁竞争?
输出结果如下:
在这里插入图片描述

结论:
在多线程进行锁竞争的过程中是不会被interrupt所干扰掉的,interrupt本质上就是设置标志位是不会干扰线程的。
interrupt是否能干扰lock呢?
用如下代码做实验:

public class T10_Interrupt_and_lock {

    private static ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            lock.lock();
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
            System.out.println("t1 end!");
        });

        t1.start();

        SleepHelper.sleepSeconds(1);


        Thread t2 = new Thread(() -> {
            lock.lock();
            try {
            } finally {
                lock.unlock();
            }
            System.out.println("t2 end!");
        });

        t2.start();

        SleepHelper.sleepSeconds(1);

        t2.interrupt();
    }
}

输出结果如下:
在这里插入图片描述
结论:
intterrupt方法干扰不到lock。

那么如何做到真正的打断正在竞争的线程呢?(使用 ReentrantLock 的 lockinterruptibly方法)

public class Interrupt_and_lockInterruptibly {

    private static ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            lock.lock();
            try {
                SleepHelper.sleepSeconds(10);
            } finally {
                lock.unlock();
            }
            System.out.println("t1 end!");
        });

        t1.start();

        SleepHelper.sleepSeconds(1);


        Thread t2 = new Thread(() -> {
            System.out.println("t2 start!");
            try {
                lock.lockInterruptibly();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
            System.out.println("t2 end!");
        });

        t2.start();

        SleepHelper.sleepSeconds(1);

        t2.interrupt();

    }
}

说明:在线程二启动的过程中调用 **lock.lockInterruptibly();**将线程二设置为可被打断的状态。
执行结果如下:
在这里插入图片描述
当执行t2的interrupt方法时,抛出InterruptedException.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值