天天看点

如何优雅得关闭线程

1,直接调用interrupt方法

public class Main {

    public static void main(String[] args) {
         Thread t = new Thread(() -> {
                while (true){
                    if (Thread.interrupted()){
                        break;
                    }
                }
                // 执行之后的操作
        });
        t.start();
        t.interrupt();
    }

}

           

问题分析:

​ while循环每次检查当前线程的关闭状态,如果关闭了,则跳出循环,执行清理之类的操作。

​ 但这样会出现一个问题,如果t线程执行得是一个相当耗时的操作,像如下代码,比如io流读取一个超大的文件,线程会一直处于阻塞直到全部读取完毕。此时主线程打断当前线程,当前线程是监听不到打断信号的。

public class Main {

    public static void main(String[] args) {
         Thread t = new Thread(() -> {
                while (true){
                    if (Thread.interrupted()){
                        break;
                    }
                    //io流读取一个超大文件,线程一直阻塞 
                }
                // 执行之后的操作
        });
        t.start();
        t.interrupt();
       

    }

}
           

2,解决办法

让执行的逻辑运行在一个后台线程中,这样可以通过关闭主线程,从而关闭掉后台线程。(暴力关闭线程)
public class ThreadService {

    private Thread executeThread;

    private boolean finished;

    public void execute(Runnable task){
        executeThread = new Thread(()->{
           Thread runner = new Thread(task);
           runner.setDaemon(true);
           runner.start();
            try {
                //让主线程等着后台线程执行完毕再结束
                runner.join();
                finished = true;
            } catch (InterruptedException e) {
//                e.printStackTrace();
            }
        });
        executeThread.start();
    }

    public void shutdown(long mills){
        long currentMills = System.currentTimeMillis();
        while (!finished){
            if (System.currentTimeMillis() - currentMills >= mills ){
                System.out.println("任务超时,需要结束");
                executeThread.interrupt();
                break;
            }
        }
    }
}

           
public class Main {

    public static void main(String[] args) {
        ThreadService threadService = new ThreadService();
        threadService.execute(() -> {
            while (true) {

            }
        });
        //main 线程关闭 executeThread 从而关闭了executeThread的后台线程
        threadService.shutdown(1000 * 3);

    }

}

           

继续阅读