并发——中断机制

1.中断概述

中断只是一种协商机制,如果要中断一个线程,需要手动调用该线程的interrupt方法,将此线程对象的中断标识设为true(默认中断标志位为false),接着我们需要手动写代码去不断的检测要中断线程的标识位,如果为true,表示别的线程请求将这条线程中断。所以说一个线程的命运是掌握在自己手中的。

2.中断的相关API——三大方法

并发——中断机制_第1张图片

3.面试常考题

3.1如何停止并中断运行中的线程?

  • 通过volatile修饰变量来实现,volatile具有可见性,别的线程修改其共用的变量来协商中断线程。

  • 使用原子类AtomicBoolean实现,也是通过别的线程修改其中的boolean类型的变量来协商中断线程。

  • 通过Thread类中自带的中断API实现,利用interrupt() 和isInterrupted()方法,要求在中断的线程中需要不断的监听中断标志位的状态。 

public class InterruptDemo {

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            while (true) {
                if (Thread.currentThread().isInterrupted()) { //自己不断的循环判断
                    System.out.println(Thread.currentThread().getName() + " isInterrupted()的值被改为true,t1程序停止");
                    break;
                }
                System.out.println("-----------hello isInterrupted()");
            }
        }, "t1");
        t1.start();

        try {
            TimeUnit.MILLISECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //t2向t1放出协商,将t1中的中断标识位设为true,希望t1停下来
        new Thread(() -> t1.interrupt(), "t2").start();

        //当然,也可以t1自行设置
        //t1.interrupt();

    }
}
/**
 * -----------hello isInterrupted()
 * -----------hello isInterrupted()
 * -----------hello isInterrupted()
 * -----------hello isInterrupted()
 * t1 isInterrupted()的值被改为true,t1程序停止
 */

3.2线程的中断标识为true,是不是被设置线程就立刻停止了?

并不是立刻停止,具体来说,当调用需要中断线程的Interrupt()方法时,有以下两种情况:

  • 如果此线程正处于正常的活动状态,那么就会设置线程的中断标志位为true,仅此而已,线程还会继续不受影响的运行。

  • 如果此线程正处于阻塞的状态(例如sleep,wait等),那么该线程将立刻退出被阻塞的状态,并且清除Interrupt的状态(设置为false),并且抛出一个InterruptedException异常

总之,中断只是一种协商机制,修改中断标识位仅此而已,并不是立刻stop打断。

3.3静态方法Thread.interrupted(),谈谈你的理解?

此方法是一个静态方法,该方法的含义是返回此线程的中断标志位的状态,并且清空中断标识位(设置为false)。这就可能会导致连续两次调用此方法,而返回回来的结果却不一致。

3.4对于interrupted()和isInterrupted()的共同点和区别?

共同点:

  • 都能返回此刻线程标志位的状态。

  • 调用的都是本地(native)的isInterrupted(boolean ClearInterrupted)方法。

并发——中断机制_第2张图片

区别:

  • interrupted()方法是静态方法,isInterrupted()方法是实例方法。

  • interrupted()方法会清空中断标志位状态(传入参数true),而isInterrupted()方法不会(传入参数false)。

 

你可能感兴趣的:(并发编程,java,开发语言)