zoukankan      html  css  js  c++  java
  • java 多线程之 interrupt()和线程终止方式

    1. interrupt() 说明
      interrupt()的作用是中断本线程。
      本线程中断自己是被允许的;其它线程调用本线程的interrupt()方法时,会通过checkAccess()检查权限。这有可能抛出SecurityException异常。
      如果本线程是处于阻塞状态:调用线程的wait(), wait(long)或wait(long, int)会让它进入等待(阻塞)状态,或者调用线程的join(), join(long), join(long, int), sleep(long), sleep(long, int)也会让它进入阻塞状态。若线程在阻塞状态时,调用了它的interrupt()方法,那么它的“中断状态”会被清除并且会收到一个InterruptedException异常。例如,线程通过wait()进入阻塞状态,此时通过interrupt()中断该线程;调用interrupt()会立即将线程的中断标记设为“true”,但是由于线程处于阻塞状态,所以该“中断标记”会立即被清除为“false”,同时,会产生一个InterruptedException的异常。
      如果线程被阻塞在一个Selector选择器中,那么通过interrupt()中断它时;线程的中断标记会被设置为true,并且它会立即从选择操作中返回。
      如果不属于前面所说的情况,那么通过interrupt()中断线程时,它的中断标记会被设置为“true”。
      中断一个“已终止的线程”不会产生任何操作。

    2. 终止线程的方式
      Thread中的stop()和suspend()方法,由于固有的不安全性,已经建议不再使用!
      下面,我先分别讨论线程在“阻塞状态”和“运行状态”的终止方式,然后再总结出一个通用的方式。
      2.1 终止处于“阻塞状态”的线程
      通常,我们通过“中断”方式终止处于“阻塞状态”的线程。
      当线程由于被调用了sleep(), wait(), join()等方法而进入阻塞状态;若此时调用线程的interrupt()将线程的中断标记设为true。由于处于阻塞状态,中断标记会被清除,同时产生一个InterruptedException异常。将InterruptedException放在适当的为止就能终止线程,形式如下:

    @Override
    public void run() {
        try {
            while (true) {
                // 执行任务...
            }
        } catch (InterruptedException ie) {  
            // 由于产生InterruptedException异常,退出while(true)循环,线程终止!
        }
    }
    

    说明:在while(true)中不断的执行任务,当线程处于阻塞状态时,调用线程的interrupt()产生InterruptedException中断。中断的捕获在while(true)之外,这样就退出了while(true)循环!
    2.2 终止处于“运行状态”的线程
    通常,我们通过“标记”方式终止处于“运行状态”的线程。其中,包括“中断标记”和“额外添加标记”。
    01 通过“中断标记”终止线程。
    形式如下:

    @Override
    public void run() {
        while (!isInterrupted()) {
            // 执行任务...
        }
    }
    

    说明:isInterrupted()是判断线程的中断标记是不是为true。当线程处于运行状态,并且我们需要终止它时;可以调用线程的interrupt()方法,使用线程的中断标记为true,即isInterrupted()会返回true。此时,就会退出while循环。
    注意:interrupt()并不会终止处于“运行状态”的线程!它会将线程的中断标记设为true。
    02 通过“额外添加标记”。
    形式如下:

    private volatile boolean flag= true;
    protected void stopTask() {
        flag = false;
    }
    @Override
    public void run() {
        while (flag) {
            // 执行任务...
        }
    }
    

    说明:线程中有一个flag标记,它的默认值是true;并且我们提供stopTask()来设置flag标记。当我们需要终止该线程时,调用该线程的stopTask()方法就可以让线程退出while循环。
    注意:将flag定义为volatile类型,是为了保证flag的可见性。即其它线程通过stopTask()修改了flag之后,本线程能看到修改后的flag的值。
    2.3 综合线程处于“阻塞状态”和“运行状态”的终止方式,比较通用的终止线程的形式如下:

    @Override
    public void run() {
        try {
            // 1. isInterrupted()保证,只要中断标记为true就终止线程。
            while (!isInterrupted()) {
                // 执行任务...
            }
        } catch (InterruptedException ie) {  
            // 2. InterruptedException异常保证,当InterruptedException异常产生时,线程被终止。
        }
    }
    
    1. interrupted() 和 isInterrupted()的区别
      interrupted() 和 isInterrupted()都能够用于检测对象的“中断标记”。
      区别是,interrupted()除了返回中断标记之外,它还会清除中断标记(即将中断标记设为false);而isInterrupted()仅仅返回中断标记。
  • 相关阅读:
    结巴分词 0.14 版发布,Python 中文分词库
    Lazarus 1.0.2 发布,Pascal 集成开发环境
    Android全屏 去除标题栏和状态栏
    服务器日志现 Android 4.2 传将添多项新特性
    Percona XtraBackup 2.0.3 发布
    长平狐 Android 强制设置横屏或竖屏 设置全屏
    NetBeans 7.3 Beta 发布,全新的 HTML5 支持
    CppDepend现在已经支持Linux
    GromJS 1.7.18 发布,服务器端的 JavaScript
    Apache OpenWebBeans 1.1.6 发布
  • 原文地址:https://www.cnblogs.com/cag2050/p/7291985.html
Copyright © 2011-2022 走看看