zoukankan      html  css  js  c++  java
  • 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异常;

  • 相关阅读:
    JavaScript界面传值与前后台互调
    @requestBody注解的使用
    mybatis动态sql中foreach标签的使用
    mybatis动态SQL中的sql片段
    mybatis动态sql中where标签的使用
    mybatis动态sql中的trim标签的使用
    mybatis动态SQL中的set标签的使用
    SQL-join(inner join)、left join、right join、full join
    Oracle-distinct()用法、count(distinct( 字段A || 字段B))是什么意思?distinct多个字段
    Oracle-where exists()、not exists() 、in()、not in()用法以及效率差异
  • 原文地址:https://www.cnblogs.com/mantu/p/5761527.html
Copyright © 2011-2022 走看看