初探JAVA的中断

曾经有人说,一个好的技术分享大概就是如下一个流程
是什么(即该软件是干什么用的)--->干什么(即该软件的使用场景)-->怎么干(即具体使用场景的具体使用示例)。 ----鲁迅
反正我是严重不同意这种说法的。因为对于这些小白听众来说,你用来描述是什么的东西对于他们来说都是 是什么。下面开始我们今天的主题 【java 的中断

中断的原理

让我们从java线程的源码分析开始好了。Thread类中定义了如下几个方法

// 中断的几个方法最终都是通过native方法实现的,关于native方法,我们之后会慢慢研究,这里不做分析
// 我们不要看这个函数里面的代码逻辑,只需要记住interrupt方法是唯一能将中断状态设置为true的方法
    public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();

        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();           // Just to set the interrupt flag
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }
// 这个函数的作用其实是清除中断标志,即将中断标志设置为false。
// 这个函数命名也真是醉了,我怎么感觉使用clearInterrupt更好啊
// 里面的逻辑我们也不用管
//反正我每次都有点搞混,后来就想了个记忆方法,interrupted表示interrupt的过去式,也就是说中断过去了,即中断标志清除了,看来学好英语很重要
    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }
    public boolean isInterrupted() {
        return isInterrupted(false);
    }

中断请求可以来自线程本身也可以来自其它线程,最终只要调用了interrupt() 方法,那么该线程就被"中断"了,这里之所以加了引号,是因为线程并没有被打断,只是中断标志位置为true了,如果线程在该标志位为true时做一些抛出异常的处理,线程就会中断,不处理就跟没事发生一样。线程A只要把线程B的中断标志位设置位true,线程B在合适的时机根据该标志位(调用isInterrupted方法)处理中断就可以了,当然也可以不处理(调用interrupted()进行清除)。

到这里,大家应该也明白了只要线程的interrupt方法被调用了,该线程就会产生中断(当然前提是你的代码中有对中断作出响应,如果没有,那有中断和没中断没啥区别)就像你妈喊你回家吃饭,但是回不回是你决定的。

在一些类中中就有些方法就会调用线程的中断方法,比如FutureTask中的cancel方法,如果传入的参数为true,就会调用。

中断的处理

java的中断,说白了就是线程直接的一种协作机制,我告诉你了,你爱听不听,你可以根据自己的实际情况(具体业务场景)选择听还是不听(处理或者不处理)。就像你上学时老师给你讲的大道理,你当时选择一概不听,等多年以后,你忽然理解了,就会选择听了。有点扯远了~

我们经常看到某些方法后面抛出InterruptedException,就说明该方法会响应中断,然后该方法的上层调用栈如果检测到中断,清除中断位,然后抛出异常,那么上层方法也成为一个可中断方法
一般的基础类库都不会吞掉该中断,让上层调用栈去处理

题外话

Thread.stop方法已经停用了,我们就不说了
stop 跟interrupt的一个核心区别就是中断需要程序自己去检测然后做相应的处理,而Thread.stop会直接在代码执行过程中抛出ThreadDeath错误

你可能感兴趣的:(初探JAVA的中断)