Thread:线程的优雅关闭

Java中不应强制杀死线程,而应使用线程间通信优雅关闭,例如设置关闭标志位。守护线程在所有非守护线程结束后导致JVM退出。中断机制如`interrupt()`和`InterruptedException`用于处理阻塞情况下的线程退出。
摘要由CSDN通过智能技术生成

线程的优雅关闭

stop与destory函数

线程是“一段运行中的代码”,一个运行中的方法。运行到一半的线程能否强制杀死?

不能。在Java中,有stop()、destory()等方法,但这些方法官方明确不建议使用。原因很简单,如
果强制杀死线程,则线程中所使用的资源,例如文件描述符、网络连接等无法正常关闭。

因此,一个线程一旦运行起来,不要强行关闭,合理的做法是让其运行完(也就是方法执行完毕),干净地释放掉所有资源,然后退出。如果是一个不断循环运行的线程,就需要用到线程间的通信机制,让主线程通知其退出。

守护线程

daemon线程和非daemon线程的对比:

public class Main {
    public static void main(String[] args) {
        MyDaemonThread myDaemonThread = new MyDaemonThread();
        // 设置为daemon线程
        myDaemonThread.setDaemon(true);
        myDaemonThread.start();
        // 启动非daemon线程,当非daemon线程结束,不管daemon线程是否结束,都结束JVM进程。
        new MyThread().start();
    }
}
public class MyDaemonThread extends Thread {
    @Override
    public void run() {
        while (true) {
            System.out.println(Thread.currentThread().getName());
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("非Daemon线程");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

对于上面的程序,在thread.start()前面加一行代码thread.setDaemon(true)。当main(…)函数退出
后,线程thread就会退出,整个进程也会退出。

当在一个JVM进程里面开多个线程时,这些线程被分成两类:守护线程和非守护线程。默认都是非
守护线程。

在Java中有一个规定:当所有的非守护线程退出后,整个JVM进程就会退出。意思就是守护线程“不
算作数”,守护线程不影响整个 JVM 进程的退出。

例如,垃圾回收线程就是守护线程,它们在后台默默工作,当开发者的所有前台线程(非守护线
程)都退出之后,整个JVM进程就退出了。

设置关闭的标志位

开发中一般通过设置标志位的方式,停止循环运行的线程。

public class MyThread extends Thread{
    
    private boolean running = true;
    
    @Override
    public void run() {
        while (running) {
            System.out.println("线程正在运行。。。");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public void stopRunning() {
        this.running = false;
    }
    
    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        Thread.sleep(5000);
        myThread.stopRunning();
        myThread.join();
    }
}

但上面的代码有一个问题:如果MyThread t在while循环中阻塞在某个地方,例如里面调用了
object.wait()函数,那它可能永远没有机会再执行 while( ! stopped)代码,也就一直无法退出循环。

此时,就要用到InterruptedException()与interrupt()函数。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员无羡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值