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

java如何正确终止线程

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

java如何正确终止线程

线程通过start()方法启动后,会在run()方法执行结束后进入终止状态。

stop()方法终止线程会导致的两个问题
  • 立即抛出ThreadDeath异常,在run()方法中任何一个执行指令都可能抛出ThreadDeath异常。
  • 会释放当前线程所持有的所有锁,这种锁的释放是不控的。

示例代码

public class ThreadStopExample extends Thread {
    public void run(){
        try {
            for (int i = 0; i < 100000; i++){
                System.out.println("Running.." + i);
            }
            System.out.println("the code that it will be executed");
        }catch (Throwable e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new ThreadStopExample();
        thread.start();
        Thread.sleep(100);
        thread.stop();
    }
}

//运行结果
Running..21584
Running..21585
Running..21586
Running..21587
Running..21588java.lang.ThreadDeath
	at java.lang.Thread.stop(Thread.java:853)
	at ThreadStopExample.main(ThreadStopExample.java:21)
运行结果发现问题
  • 在run()方法中,代码System.out.println("the code that it will be executed");还没有执行,就因为ThreadDeath异常导致线程中断了,造成业务处理的不完整性。
  • 观察内容Running..21588java.lang.ThreadDeath,我们使用的是println()方法,但是这里并没有换行,原因如下:
//println()方法的源码
  public void println(String x) {
        synchronized (this) {
            print(x);
            newline();
        }
    }
Interrupt安全中断线程

在Thread中提供了一个interrupt()方法,用来向指定线程发送中断信号,收到该信号的线程可以使用isInterrupted()方法来判断是否被中断。

public class InterruptExample extends Thread{
    public void run(){
        int i = 0;
        while (!Thread.currentThread().isInterrupted()){
            i++;
        }
        System.out.println("线程已被中断,i=" + i);
    }

    public static void main(String[] args) throws InterruptedException {
        InterruptExample interruptExample = new InterruptExample();
        interruptExample.start();
        TimeUnit.SECONDS.sleep(1);
        System.out.println(interruptExample.isInterrupted());
        interruptExample.interrupt();
        System.out.println(interruptExample.isInterrupted());
    }
}

//运行结果
false
true
线程已被中断,i=1523199841

interrupt()方法并没有武断的把运行中的线程停止,而是通过传递标识的方式让运行的线程自己决定是否停止。这意味着该线程在收到该信号后,可以继续把run()方法中的指令运行完成,最后让run()方法安全执行结束,完成线程的中断功能。

中断处于阻塞状态下的线程

如果线程因为sleep()、Object.wait()等方法阻塞,而其他线程想通过interrupt()方法对该线程进行中断,那么这个线程必须先被唤醒,否则无法响应中断信号。

public class BlockedThreadInterruptExample extends Thread{
    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()){
            try {
                TimeUnit.SECONDS.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();  //加上这行代码才能真正中断阻塞线性不加这行代码程序是一直运行的状态说明线程并没有真正的被中断。
            }
            System.out.println("线程被中断");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        BlockedThreadInterruptExample blockedThreadInterruptExample = new BlockedThreadInterruptExample();
        blockedThreadInterruptExample.start();
        TimeUnit.MICROSECONDS.sleep(100);
        System.out.println(blockedThreadInterruptExample.isInterrupted());
        blockedThreadInterruptExample.isInterrupted();
        System.out.println(blockedThreadInterruptExample.isInterrupted());
    }
}

//运行结果
false
true
线程被中断
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at java.lang.Thread.sleep(Thread.java:340)
	at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
	at BlockedThreadInterruptExample.run(BlockedThreadInterruptExample.java:12)

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

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

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