• Java线程专题 4:线程停止


    在Java中以下3种方法可以终止正在运行的线程:

      1. 使用退出标志,使线程正常退出,也就是当run方法执行完后自行结束。

      2. 使用线程的stop方法,但不推荐,已过时方法。

      3. 使用interrupt中断线程

    理解中断:

      中断可以理解为线程的一个标识位属性,它表示一个运行中的线程是否被其他线
    了中断操作。中断好比其他线对该线程打了个招呼,其他线程通过调该线程的interrupt()
    方法行中断操作。

    线程通过检查自身是否被中断来行响线程通方法isInterrupted()行判断是否
    被中断,也可以用静方法Thread.interrupted()当前线程的中断标识行复位。如果
    线程已经处终结,即使该线程被中断,在该线象的isInterrupted()依旧会返
    false
    1. interrupt使用

    interrupt方法使用时,表示在当前线程(调用该方法的Thread实例所代表的线程)中打了一个停止标志,并不是真正停止线程,线程仍然继续执行。

    如果线程处于被阻塞状态(例如处于sleep, wait, join 等状态),那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常

    public class Main {
    
        public static void main(String[] args) throws InterruptedException {
            MyThread thread = new MyThread();
            thread.start();
            TimeUnit.SECONDS.sleep(2);
            thread.interrupt();
        }
    }
    
    class MyThread extends Thread {
        @Override
        public void run() {
            for (int j = 0; j < 100000; j++) {
                System.out.println("j=" + j);
            }
        }
    }
    

      

    2.interrupted方法

    测试当前线程(当前执行方法的线程)是否已被中断,此线程清除线程的中断状态,即:连续调用两次该方法,第二次将返回false

    public class Main {
    
        public static void main(String[] args) throws InterruptedException {
            MyThread thread = new MyThread();
            thread.start();
            thread.interrupt();
            System.out.println("1:"+thread.interrupted());
            System.out.println("2:"+thread.interrupted());
            Thread.currentThread().interrupt();
            System.out.println("1:"+thread.interrupted());
            System.out.println("2:"+thread.interrupted());
        }
    }
    class MyThread extends Thread {
        @Override
        public void run() {
            for (int j = 0; j < 100000; j++) {
                System.out.println("j=" + j);
            }
        }
    }
    

      

    从控制台打印的结果来看,interrupted()方法测试当前线程是否已经中断。这个当前线程是main,它从未中断过,所以前面打印的结果是两个false.

    接着使用当前线程中断方法,两次打印第二次返回为false.

     3.isInterrupted

    测试此线程(调用该方法的Thread实例所代表的线程)是否被中断 ,不清除中断状态

    public class Main {
    
        public static void main(String[] args) throws InterruptedException {
            MyThread thread = new MyThread();
            thread.start();
            thread.interrupt();
            System.out.println("1:"+thread.isInterrupted());
            System.out.println("2:"+thread.isInterrupted());
        }
    }
    class MyThread extends Thread {
        @Override
        public void run() {
            for (int j = 0; j < 100000; j++) {
                System.out.println("j=" + j);
            }
        }
    }
    

      

    总结

      关于这三个方法,interrupt()是给线程设置中断标志;

              interrupted()是检测中断并清除中断状态;

              isInterrupted()只检测中断。

      interrupted()作用于当前线程,interrupt()和isInterrupted()作用于此线程,即代码中调用此方法的实例所代表的线程。

    有了上面的基础再来看看停止线程

    1. 中断+异常

    public class Main {
    
        public static void main(String[] args) throws InterruptedException {
            MyThread thread = new MyThread();
            thread.start();
            TimeUnit.SECONDS.sleep(1);
            thread.interrupt();
        }
    }
    class MyThread extends Thread {
        @Override
        public void run() {
            try {
                for (int j = 0; j < 1000000; j++) {
                    if(Thread.currentThread().isInterrupted()){
                        System.out.println("线程终止。。");
    //                    break;
                        throw new InterruptedException();
                    }
                    System.out.println("j=" + j);
                }
                System.out.println("doing ..");
            }catch (InterruptedException e){
                System.out.println("catching ..");
            }
        }
    }
    

      由于直接判断中断标志,循环break后,循环外会继续执行,可以用跑出异常来中断该线程执行。

    2.中断+return

        public void run() {
            for (int j = 0; j < 1000000; j++) {
                if(Thread.currentThread().isInterrupted()){
                    System.out.println("线程终止。。");
                    return;
                }
                System.out.println("j=" + j);
            }
            System.out.println("doing ..");
        }
    

      正确停止线程对业务系统数据完整性是非常有必要的,过标识位或者中断操作的方式能使线程在有机会去清理源,而不是武断地
    线程停止 。

     

  • 相关阅读:
    2015.2.27 UltraEdit中显示XML结构
    2015.1.31 DataGridView自动滚动到某行
    2015.1.15 利用函数实现将一行记录拆分成多行记录 (多年想要的效果)
    2015.1.15 利用Oracle函数返回表结果 重大技术进步!
    2015.1.15 利用Oracle函数插入表结构 Bulk collect into 不用循环,简洁高效
    2015.1.8 Left join 左连接
    2015.1.10 解决DataGridView SelectionChanged事件自动触发问题
    delphi 遍历窗口
    delphi 访问 protected 属性 哈哈
    clientdataset 读取excel 如果excel 文件不存在的时候 相应的gird 会不显示数据, 鼠标掠过 gird 格子 才会显示数据。 这是一个bug 哈哈
  • 原文地址:https://www.cnblogs.com/gcm688/p/12893612.html
Copyright © 2020-2023  润新知