Java并发编程基础构建模块(04)——线程阻塞与中断

来源:互联网 发布:日本第五师团知乎 编辑:程序博客网 时间:2024/05/16 16:36

        我们都知道线程始终处于以下几种状态之一,这里我们说说阻塞(Blocked)和中断阻塞:

        

        线程阻塞有很多原因,比如等待IO操作,等待获得锁,调用了sleep()、wait()、join()等等方法。当线程阻塞时,处于3种状态的1种,BLOCKED,WAITING,TIMED_WAITING。

        BLOCKED:处于等待锁的状态,只有获得锁,才能脱离阻塞状态;

        WAITING:如果是因为join()方法进入等待的话,在目标thread执行完毕之后,会回到就绪状态;如果是因为wait()方法进入等待的话,在锁对象执行notify()或者notifyAll()之后会回到就行状态;

        TIMED_WAITING:与WAITING状态类似,进入等待的方法也一样,只不过有时间限制,时间到了自动进入就绪状态。

        JDK类库中,通常情况下,线程进入阻塞时的方法会抛出一个InterruptedException,也就是说,通常某些方法抛出InterruptedException,表示该方法是一个阻塞方法。

        Thread提供了interrupt()方法,用于中断线程或查询线程是否已经被中断。中断是一种协作机制,一个线程无法停止其他线程正在执行的操作,如当线程A要中断B时,A仅仅能修改B的中断状态属性,修改后,线程B在执行到某个可暂停的地方时,如果可能的话,才会停下来。这种情况最常见的就是取消某个操作,方法对中断请求的响应速度越高,就越容易及时取消某些操作。

        代码中调用一个阻塞方法时,通常会抛出InterruptedException,此时你需要对阻塞方法提供被中断时的操作,通常有2种情况:

        1、 传递异常,就是不捕获该异常,或者捕获后进行一些操作(如清理,日志等)后再抛出该异常,让调用者自己处理中断情况,这是最好的办法。

        2、 某些情况下必须捕获这个异常(如run()中)时,可以调用当前线程的interrupt()方法,让当前线程恢复中断状态。

        

        为什么要恢复中断状态:从JDK的API中可以看到

        

        也就是说,线程从阻塞状态被调用interrupt中断阻塞时,状态会恢复成未中断,如果不进行任何处理往下执行的话,根本没有留下阻塞,被中断的证据,所以要重新恢复一下中断状态,已留下证据,提供给后续使用。

        当然,还有其他更复杂的方法处理中断情况,也要根据实际情况处理,不过上面这2种情况已经能处理大部分情况了。

0 0