多线程的终止方法(停止线程)

多线程的终止方法

多线程的终止共有3种方法

  1. run方法执行结束,正常退出
  2. 异常终止
  3. 暴力终止

停止线程

停止线程是多线程中的一个重要技术点,本篇文章将对线程的停止操作进行详细讲解。

Thread类中是有一个方法 interrupt() ,虽然该方法命名为“终止”,但是它并不会立马终止当前线程,它只令当前线程终止状态为true。

停止线程不能像for或while循环中使用break停止那样直接,而是需要一些技巧来终止。


如何判断线程已终止

Thread类中提供了两个方法:

  • public static boolean interrupted()
  • public boolean isInterrupted()

两者的区别如下:
interrupted方法是测试当前线程是否已经中断,当前线程指运行该方法的线程。执行后具有将状态标志清除为false的功能。也就是说在第一次调用成功停止之后,第二次调用该方法就会返回false。
isInterrupted方法是测试线程Thread对象是否已经是中断状态,但不清除状态标志。


异常终止

这个方法的意思就是在判断到线程终止标志为真后,抛出异常终止当前线程。
示例代码如下:

public class Test {
    public static void main(String[] args) {
        try {
            MyThread thread = new MyThread();
            thread.start();
            Thread.sleep(1000);
            thread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class MyThread extends Thread {
    @Override
    public void run() {
        try {
            for (int i = 0 ; i < 1000000 ; i++) {
                if (this.interrupted()) {
                    System.out.println("为停止状态!线程退出!");
                    throw new InterruptedException();
                }
                System.out.println("i -- " + i);
            }
            System.out.println("for 循环之下的代码");
        } catch (InterruptedException e) {
            System.out.println("进入catch代码块,线程结束执行正常");
            e.printStackTrace();
        }
    }
}

运行结果如下:
在这里插入图片描述
我们可以看到,线程成功中止。


暴力终止

暴力终止其实就是使用Thread类中的 stop() 方法,这种终止线程的方法是直接终止当前线程,有安全隐患。
示例代码:

public class Test {
    public static void main(String[] args) {
        try {
            MyThread thread = new MyThread();
            thread.start();
            thread.sleep(100);
            thread.stop();
            System.out.println("finished");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0 ; i < 1000000 ; i++) {
            System.out.println("i -- " + i);
        }
    }
}

运行结果:
在这里插入图片描述
我们会发现这里System.out.println("i – " + i);语句甚至都没有执行结束,我的线程就已经结束并回到了主方法中执行后续语句了。


暴力终止出现的问题

stop()方法会抛出java.lang.ThreadDeath异常

通常情况下可以不显式地捕捉此异常,下面是测试项目:

public class Test {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
    }
}
public class MyThread extends Thread {
    @Override
    public void run() {
        try {
            this.stop();
        } catch (ThreadDeath e) {
            System.out.println("抛出ThreadDeath");
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

stop()方法会对锁定对象“解锁”

使用 stop() 会释放锁,而释放锁将会对数据造成不同步的非线程安全问题,如果出现此现象,程序处理的数据就会被破坏,最终导致程序出错。这里博主就不演示了,大家记住就好,stop方法也在JDK中已经被标注过期,因此我们在开发时也不会使用这个方法来进行线程终止的操作。


使用return终止线程

结合interrupt()和return是可以有效终止线程的,但是不提倡使用这个方法,代码中可能出现多个return,逻辑有可能会变得复杂,最重要的是这样会造成污染。


总结

由上面的例子我们可以得出,在项目开发的过程中,如果有要对线程进行终止操作的需求时,尽可能地去使用interrupt()方法+抛异常的方法进行终止线程,其他的方法一般都不推荐,毕竟其他方法多多少少都是有些问题的。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值