中断线程

结束一个线程,我们要分析线程的运行情况.也就是线程正在干什么.如果那个孩子什么事也没干,那就让他立即去睡觉.而如果那个孩子正在摆弄他的玩具,我们就要让它把玩具收拾好再睡觉.

 所以一个线程从运行到真正的结束,应该有三个阶段:

  1. 正常运行.
  2. 处理结束前的工作,也就是准备结束
  3. 结束退出.

 在我的JDBC专栏中我N次提醒在一个SQL逻辑结束后,无论如何要保证关闭Connnection那就是在finally从句中进行.同样,线程在结束前的工作应该在finally中来保证线程退出前一定执行:

try {
            // 正在逻辑
    } catch (Exception e) {
}
finally { // 清理工作 }

那么如何让一个线程结束呢?既然不能调用stop,可用的只的interrupt()方法.interrupt()方法只是改变了线程的运行状态,如何让它退出运行?

 对于一般逻辑,只要线程状态为已经中断,我们就可以让它退出,所以这样的语句可以保证线程在中断后就能结束运行:

while (!isInterrupted()) {
            // 正常逻辑
    }

 这样如果这个线程被调用interrupt()方法,isInterrupted()为true,就会退出运行.但是如果线程正在执行wait,sleep,join方法,你调用interrupt()方法,这个逻辑就不完全了.

 如果一个有经验的程序员来处理线程的运行的结束:

    public void run() {
        try {
            while (!isInterrupted()) {
                // 正常工作
            }
        } catch (Exception e) {
            return;
        } finally {
            // 清理工作
        }

    }

我们看到,如果线程执行一般逻辑在调用innterrupt后.isInterrupted()为true,退出循环后执行清理工作后结束,即使线程正在wait,sleep,join,也会抛出异常执行清理工作后退出.

这看起来非常好,线程完全按最我们设定的思路在工作.但是,并不是每个程序员都有这种认识,如果他聪明的自己处理异常会如何?事实上很多或大多数程序员会这样处理:

public void run() {
        while (!isInterrupted()) {
            try {
                // 正常工作
            } catch (Exception e) {
                // nothing
            } finally {

            }
        }
    }

 想一想,如果一个正在sleep的线程,在调用interrupt后,会如何? wait方法检查到isInterrupted()为true,抛出异常,而你又没有处理.而一个抛出了InterruptedException的线程的状态马上就会被置为非中断状态,如果catch语句没有处理异常,则下一次循环中isInterrupted()为false,线程会继续执行,可能你N次抛出异常,也无法让线程停止.

 那么如何能确保线程真正停止?在线程同步的时候我们有一个叫"二次惰性检测"(double check),能在提高效率的基础上又确保线程真正中同步控制中.那么我把线程正确退出的方法称为"双重安全退出",即不以isInterrupted()为循环条件.而以一个标记作为循环条件:

class MyThread extends Thread {
    private boolean isInterrupted = false;// 这一句以后要修改
    public void interrupt() {
        isInterrupted = true;
        super.interrupt();
    }

    public void run() {
        while (!isInterrupted) {
            try {
                // 正常工作
            } catch (Exception e) {
                // nothing
            } finally {

            }
        }
    }
}

试试这段程序,可以正确工作吗?对于这段程序仍然还有很多可说的地方,先到这里吧

posted @ 2016-03-07 20:12  程序猿进化之路  阅读(133)  评论(0)    收藏  举报