停止线程

本文介绍了Java中三种停止线程的方法:使用退出标志使线程正常退出、使用stop方法强行退出(不推荐)、使用interrupt方法中断线程。并通过示例演示了如何正确使用interrupt方法配合异常处理来安全地停止线程。

Java 中有以下三种停止线程的方法:

  1. 使用 退出标志,使线程正常退出,也就是当 run 方法完成后终止线程。
  2. 使用 stop 方法 强行退出,但是不推荐这个方法,因为 stop 和 suspend 及 resume 一样,都是作废过期的方法,使用它们可能产生不可预料的后果(后文有详细说明)
  3. 使用 interrupt 方法 中断线程

停不了的线程

本示例将调用 interrupt() 方法来停止线程,但 interrupt() 方法的使用效果并不像 for+break 语句那样,马上就停止循环。调用 interrupt() 方法仅仅是在当前线程中打上一个停止标记,并不是真正停止线程。

public class t11 {
    public static void main(String[] args) {
        try {
            Mythread thread = new Mythread();
            thread.start();
            Thread.sleep(2000);
            thread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

class Mythread extends Thread {
    public void run() {
        for(int i=0; i<50000; i++){
            System.out.println("i = "+i);
        }
    }
}

image_1as4ormhhcavo86oh9vie1uni9.png-7.7kB

正如你所看到的,interrupt() 方法并没有停止线程。那么我们应该如何让线程停止呢?

注:如果你不是很清楚 interrupted() 和 isInterrupted() 的区别 请先阅读我的这篇博客 interrupted() 和 isInterrupted() 的区别


能停止的线程——异常法

当线程调用 interrupt 后,会将状态标志(是否中断)修改成为 true,那么我们就可以在线程中用 if 语句判断一下线程是否是停止状态,如果是停止状态,则后面代码不再运行即可。

public class t15 {
    public static void main(String[] args) {
        try {
            Thread thread = new MyThread15();
            thread.start();
            Thread.sleep(1000);
            thread.interrupt();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("------------- main end -------------");
    }
}

class MyThread15 extends Thread{
    public void run(){

        for (int i = 0; i < 500000; i++) {
            if(this.interrupted()){
                System.out.println("已经停止状态了!我要退出了!!!");
                break;
            }
            System.out.println("i= "+ i);
        }

        System.out.println("------------ 我是 thread 的 end --------------");
    }
}

image_1as4u398jeuk1gbp13n17v8j7vm.png-12.9kB

你可以看到,虽然线程停止了,但是如果 for 下面还有语句的话线程还是会继续执行。那么我们需要改进下代码,让线程直接结束掉。

package com.thread.interrupt;


public class t16 {
    public static void main(String[] args) {
        try {
            Thread thread = new MyThread16();
            thread.start();
            Thread.sleep(1000);
            thread.interrupt();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("------------- main end -------------");
    }
}

class MyThread16 extends Thread{
    public void run(){

        try {
            for (int i = 0; i < 500000; i++) {
                if(this.interrupted()){
                    System.out.println("已经停止状态了!我要退出了!!!");
                    throw new InterruptedException();
                }
                System.out.println("i= "+ i);
            }

            System.out.println("------------ 我是 thread 的 end --------------");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

image_1as4ujhavvv61re217no19j61lfu13.png-21.9kB


使用 return 停止线程

将 interrupt() 方法与 return 结合也能实现停止线程的效果

public class t18 {
    public static void main(String[] args) {
        try {
            Thread thread = new MyThread18();
            thread.start();
            Thread.sleep(2000);
            thread.interrupt();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

class MyThread18 extends Thread {
    public void run() {
        while (true) {
            if (interrupted()) {
                System.out.println("停止了!!!");
                return;
            }
            System.out.println(1);
        }
    }
}

image_1as505olu8blos217bues31lgb1t.png-6.2kB

虽然线程停止了,但是还是建议使用抛出异常的方式来停止线程,因为在 catch 块中可以对异常的信息进行相关处理,而且使用异常流能更好、更方便的控制程序运行流程,不至于代码中出现多个 return; 造成污染。


能停止的线程——暴力停止

使用 stop() 方法停止线程是非常暴力的。

public class t17 {
    public static void main(String[] args) {
        try {
            Mythread11 thread = new Mythread11();
            thread.start();
            Thread.sleep(2000);
            thread.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

class Mythread17 extends Thread {
    public void run() {
        int i = 0;
        while (true) {
            System.out.println("i = " + i++);
        }
    }
}

image_1as4v31l21rdcsc31mdc1tcf7u11g.png-7kB

线程戛然而止。而且会伴随着一些列问题:

  1. 调用 stop() 方法会抛出 java.lang.ThreadDeth 异常。
  2. 调用 stop() 方法会释放锁资源,导致数据不一致性产生。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值