关于线程中断的理解

什么是中断?中断可以理解为线程的一个标识位属性,代表一个运行中的线程是否被其他线程进行了中断操作。它是一种协作机制,线程可以通过这种机制来通知另一个线程,告诉它在合适的或者可能的情况下停止当前工作,并转而执行其他的工作。

interrupt()方法

我们知道,要想中断一个线程,那么就调用该线程的interrupt()方法,然后该线程就被中断了。然后呢?线程就停止运行了吗?当然不是,这取决于线程执行的方法是否是响应中断的。什么叫响应中断?就是在run方法中,会在运行时不断的检查中断标志,如果中断标志为true,表明线程被中断了,那么接下来线程是继续运行还是立即停止,或者在停止前执行一些其他方法,这取决于线程自身的中断策略。

为什么不是调用interrupt()方法后,线程理解停止?因为线程中断的思想是基于:一个线程不应该由其他线程强制中断或停止,而是应该由线程自己自行停止的思想。如果一个线程调用另一个线程的interrupt()方法后,被中断线程如果立即停止的话,那么这会带来一些问题:如资源没有及时释放,数据库连接未关闭,数据丢失,甚至是死锁问题等等。这就是suspend和resume和stop方法过期的原因(它们都是抢占式的,interrupt是协作式的)。因此,调用interrupt()并不意味着立即停止目标线程正在进行的工作,而只是传递了请求中断的消息(即把中断标志设置为了true)。

中断策略

《Java并发编程实战》中说过:通常,中断是线程实习取消的最合理的方式。这正是因为中断是一种非常温和的关闭方法,不会带来负面影响。

因此中断最主要的作用就是取消一个任务,并且被中断的任务中应该实现自己的中断策略:规定线程如何解释某个中断请求---当发现中断请求时,应该做那些工作,那些单元是原子操作,以及以多快速度来响应中断。

interrupted()方法:测试当前线程的中断状态,并会重置当前线程的中断状态

interrupted()是Thread的静态方法:内部实现是调用的当前线程的isInterrupted(),并且会重置当前线程的中断状态。

当前线程未被中断:第一次调用interrupted()返回false,第二次依然返回false。

当前线程被中断:第一次调用interrupted()返回true,第二次返回false。(重置当前线程的中断状态)

public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }

isInterrupted()方法。

isInterrupted()是线程对象的实例方法,不会重置当前线程的中断状态

当前线程未被中断:第一次调用isInterrupted()返回false,第二次依然返回false。

当前线程被中断:第一次调用isInterrupted()返回true,第二次返回true。(不重置当前线程的中断状态)

  @HotSpotIntrinsicCandidate
    private native boolean isInterrupted(boolean ClearInterrupted);

 

关于线程中断的两条原则:

1)除非你知道线程的中断策略,否则不应该中断它。 
这条原则告诉我们,不应该直接调用Executer之类框架中线程的interrupt方法,应该利用诸如Future.cancel的方法来取消任务。

2)任务代码不该猜测中断对执行线程的含义。 
这条原则告诉我们,一般代码遇在到InterruptedException异常时,不应该将其捕获后“吞掉”,而应该继续向上层代码抛出。

posted on 2020-10-26 18:38  菜鸟向前冲冲冲  阅读(1034)  评论(1编辑  收藏  举报