栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Java】多线程(2)终止线程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Java】多线程(2)终止线程

终止线程
      • 【Java】多线程(2)终止线程
  • 1. stop()方法
  • 2. 利用线程标志位终止线程
  • 3. 利用interrupt()中断线程

【Java】多线程(2)终止线程

​ 在JAVA中有三种方式去停止线程:

  1. 暴力停止,利用stop()方法,但已被废弃,官方不建议使用。
  2. 利用线程标志位终止线程。
  3. 利用interrupt方法来请求终止线程。
1. stop()方法

为什么弃用stop:

  1. 调用 stop() 方法会立刻停止 run() 方法中剩余的全部工作,包括在 catch 或 finally 语句中的,并抛出ThreadDeath异常(通常情况下此异常不需要显示的捕获),因此可能会导致一些清理性的工作的得不到完成,如文件,数据库等的关闭。
  2. 调用 stop() 方法会立即释放该线程所持有的所有的锁,导致数据得不到同步,出现数据不一致的问题。

例如:Thread1被停止stop()后,立即释放内存锁;Thread3获得内存锁,马上加锁。Thread1根本没有清理内存的机会,原来写数据写到一半,现在没有机会继续写了,因为线程被杀掉了;接着,Thread3获得了时间片,开始读数据时发现内存状态异常,读到一个莫名其妙的数据,因为Thread1还没清理干净就停止线程了,留下一个烂摊子给Thread3,Thread3也会面临crash。所以,这样的停止操作是非常危险的。也正是这个原因,无论什么语言都把停止的api废弃了。

2. 利用线程标志位终止线程

1、建议线程正常停止—>利用次数,不建议死循环

2、建议使用标志位—>设置一个标志位

3、不要使用stop和destroy等过时或者jdk不建议使用的方法

public class TestStop implements Runnable{
    //1、设置一个标志位
    private boolean flag =true;
    @Override
    public void run() {
        int i = 0;
        while (flag){
            System.out.println("run Thread"+i++);
        }
    }
    //2、设置一个公开的方法停止
    public void stop(){
        this.flag = false;
    }

    public static void main(String[] args) {
        Thread testThread = new Thread(new TestStop(),"InterruptionInJava");
        //TestStop testStop = new TestStop();
         //new Thread(testStop).start();

        for (int i = 0; i < 100; i++) {
            if (i==66){
                //调用stop方法返回标志位,让线程停止
                testThread.stop();
                System.out.println("线程该停止啦");
            }
            System.out.println("main"+i);
        }
    }
}
3. 利用interrupt()中断线程

当对一个线程调用interrupt方法时,就会设置线程的中断状态。这是每个线程都有的boolean标志。每个线程都应该不时地检查这个标志,以判断线程是否被中断。

public class InterruptionInJava implements Runnable{
    private volatile static boolean on = false;
    public static void main(String[] args) throws InterruptedException {
        Thread testThread = new Thread(new InterruptionInJava(),"InterruptionInJava");
        //start thread
        testThread.start();
        Thread.sleep(1000);
        InterruptionInJava.on = true;
        testThread.interrupt();

        System.out.println("main end");

    }

    @Override
    public void run() {
        while(!on){
            try {
                Thread.sleep(10000000);
            } catch (InterruptedException e) {
                System.out.println("caught exception right now: "+e);
            }
        }
    }
}

输出:

main end
caught exception right now: java.lang.InterruptedException: sleep interrupted

从上面可以看出来,确实被中断了,但是看不出中断的过程。

这就需要调用另外两个与线程有关的中断方法:

public boolean Thread.isInterrupted() //判断是否被中断 

public static boolean Thread.interrupted() //判断是否被中断,并清除当前中断状态

这两个方法使得当前线程能够感知到是否被中断了(通过检查标志位)。

package com.state;

public class InterruptTest implements Runnable{

    public static void main(String[] args) throws InterruptedException {
        Thread testThread = new Thread(new InterruptTest());
        //start thread
        testThread.start();
        Thread.sleep(1000);

        testThread.interrupt();

        System.out.println("main end");

    }

    @Override
    public void run() {

            for (int i = 0; i < 1000000; i++) {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    System.out.println("caught exception right now: "+e);
                }
                if(Thread.currentThread().isInterrupted()){
                    break;
                }
                System.out.println("运行到第"+i+"次");
            }
            System.out.println("中断执行完成");

    }
}

这个结果跑完要很久,可以把这段语句删除:

try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    System.out.println("caught exception right now: "+e);
                }

分别跑一下试一试。
结果是在抛出异常过了很久,程序才停止。

从这个例子可以看出,interrupt()与标志位法很相似但,而且有时并不会立即执行程序。

只有在遇到 sleep() 或者 wait() 这样的操作,用到Interrupt()中断方法比较好。

附一个大佬对停止线程的面试题链接:https://zhuanlan.zhihu.com/p/368149930

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/284774.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号