当前位置: 首页 > 图灵资讯 > java面试题> 金三银四精选java面试题-怎么关闭线程池?

金三银四精选java面试题-怎么关闭线程池?

来源:图灵教育
时间:2024-01-05 10:49:05
 

怎么关闭线程池?

可以通过调用线程池的shutdown或shutdownNow方法来关闭线程池。它们的原理是遍历线程池中的工作线程,然后逐个调用线程的interrupt方法来中断线程,所以无法响应中断的任务可能永远无法终止。

shutdown:将线程池状态置为shutdown,并不会立即停止:

  1. 停止接收外部submit的任务
  2. 内部正在跑的任务和队列里等待的任务,会执行完
  3. 等到第二步完成后,才真正停止

shutdownNow:将线程池状态置为stop。一般会立即停止,事实上不一定:

  1. 和shutdown()一样,先停止接收外部提交的任务
  2. 忽略队列里等待的任务
  3. 尝试将正在跑的任务interrupt中断
  4. 返回未执行的任务列表

shutdown 和shutdownnow区别如下

  • shutdownNow:能立即停止线程池,正在跑的和正在等待的任务都停下了。这样做立即生效,但是风险也比较大。
  • shutdown:只是关闭了提交通道,用submit()是无效的;而内部的任务该怎么跑还是怎么跑,跑完再彻底停止线程池。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author 百里
 */
public class BaiLiShutdownDemo {
    public static void main(string[] args) {
        // 创建一个线程池,包含两个线程
        ExecutorService executor = Executors.newFixedThreadPool(2);

        // 提交任务到线程池
        executor.submit(() -> {
            try {
                Thread.sleep(30000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println("Task 1 finished");
        });

        executor.submit(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println("Task 2 finished");
        });

        // 关闭线程池
        executor.shutdown();

        while (!executor.isTerminated()) {
            System.out.println("Waiting for all tasks to finish...");
            try {
                // 每500毫秒检查一次
                Thread.sleep(500);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }

        System.out.println("All tasks finished");
    }
}
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author 百里
 */
public class BaiLiShutdownNowDemo {
    public static void main(String[] args) {
        // 创建一个线程池,包含两个线程
        ExecutorService executor = Executors.newFixedThreadPool(2);

        // 提交任务到线程池
        executor.submit(() -> {
            while (!Thread.interrupted()) {
                System.out.println("Task 1 running...");
            }
            System.out.println("Task 1 interrupted");
        });

        executor.submit(() -> {
            while (!Thread.interrupted()) {
                System.out.println("Task 2 running...");
            }
            System.out.println("Task 2 interrupted");
        });

        // 关闭线程池
        List<Runnable> unfinishedTasks = null;
        executor.shutdownNow();

        try {
            // 等待直到所有任务完成或超时60秒
            if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                // 如果等待超时,则记录未完成的任务列表
                unfinishedTasks = executor.shutdownNow();
                System.out.println("Some tasks were not finished");
            }
        } catch (InterruptedException e) {
            // 如果等待过程中发生异常,则记录未完成的任务列表
            unfinishedTasks = executor.shutdownNow();
            Thread.currentThread().interrupt();
        }

        if (unfinishedTasks != null && !unfinishedTasks.isEmpty()) {
            System.out.println("Unfinished tasks: " + unfinishedTasks);
        } else {
            System.out.println("All tasks finished");
        }
    }
}