lesson6:java线程中断

正常的情况下,业务系统都不会去中断它的线程,但是由于一些特殊情况的发生,线程已经不能正常结束了,并且此类线程已经影响到业务系统提供服务的能力,如果系统设计的健壮,便会通过监控线程去主动的中断此类线程。但是如果随意的去中断线程,又是非常危险的,因为线程内部会占用资源和改变变量的内容等,最好的办法是向线程发送中断信号,由线程自己去中断自己。

源码地址:https://github.com/mantuliu/javaAdvance

首先,我们先分析一下源代码用demo来看一下,stop()和suspend()方法的问题:

    public final void stop() {
        stop(new ThreadDeath());
    }

    public final synchronized void stop(Throwable obj) {//注意这里用了同步标识
        if (obj == null)
            throw new NullPointerException();

        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            checkAccess();
            if ((this != Thread.currentThread()) ||
                (!(obj instanceof ThreadDeath))) {
                security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
            }
        }
        // A zero status value corresponds to "NEW", it can't change to
        // not-NEW because we hold the lock.
        if (threadStatus != 0) {
            resume(); // Wake up thread if it was suspended; no-op otherwise 如果线程是suspended的,还有个唤醒操作,有可能会发生死锁
        }

        // The VM can handle all thread states
        stop0(obj);//停止线程,未恢复已用的变量状态
    }

看了以上代码,有3点推论:1.stop()线程因为是从外部干掉的,对于业务上使用的变量没有将其状态还原;2.stop()方法没有抛出异常,用户没有得到警告3.如果对线程对象本身加了锁并且一直没有释放,例如调用suspend()方法,那么此线程通过stop()方法不能被停止;

demo Class Lesson6ThreadStopLock 已经展示了结论1和2;

demo Class Lesson6ThreadStopDeadLock展示了结论3,并证明了suspend方法因为不释放与线程相关的任何锁资源,容易造成死锁。

 既然我们不能使用stop()方法去中断线程,我们应该使用什么方法呢,在本文的开头我们提到了向目标线程发送中断信号,由它自行中断,这个中断指令就是interrupt()方法,在和线程相关的很多方法及关键字中,有一些是不响应中断的,例如:Lock类的lock()方法、Condition类的awaitUninterruptibly()方法、synchronized关键字等。

demo Class Lesson6InterruptSync 展示了synchronized不响应中断;

demo Class Lesson6InterruptLock 展示了lockInterruptibly()方法可以响应中断,并抛出java.lang.InterruptedException异常;

posted @ 2016-08-17 20:04  【刘光亮】  阅读(249)  评论(0编辑  收藏  举报