1. 什么是线程池
线程池是一种线程管理机制,用于管理和复用线程,以提高程序的性能和资源利用率。在多线程编程中,创建和销毁线程是一项开销较大的操作,因此通过线程池可以预先创建一定数量的线程,并维护一个线程队列,以便在需要时重复利用这些线程,从而避免不断地创建和销毁线程带来的性能开销。
2. 为什么使用线程池
使用线程池主要是为了提高程序的性能和资源利用率,同时降低系统开销。
- 降低线程创建和销毁的开销: 线程的创建和销毁是比较耗费系统资源的操作。通过线程池,可以预先创建一定数量的线程,并在需要时重复利用这些线程,避免不断地创建和销毁线程带来的开销。
- 提高响应速度: 线程池中的线程可以立即执行任务,而不需要等待新线程的创建。这可以大大缩短任务的等待时间,提高系统的响应速度。
- 控制资源使用: 通过限制线程池中线程的数量,可以有效地控制系统资源的使用。可以根据系统的负载情况动态调整线程池的大小,防止线程数量过多导致系统资源耗尽。
- 提高系统稳定性: 合理使用线程池可以避免因线程数量过多导致系统崩溃或过载的情况发生。通过控制线程池的大小,可以确保系统在负载高峰期也能保持稳定运行。
- 统一管理和监控: 使用线程池可以更方便地管理和监控线程的运行状态。可以通过线程池管理器来监控线程池的运行情况,对线程的创建、执行和销毁进行统一管理。
3. 如何创建线程池
在Java中,可以使用 java.util.concurrent 包提供的 ThreadPoolExecutor 类来创建线程池,通过 Executor 框架的工具类 Executors 来创建创建不同类型的线程池。
方式一:通过 ThreadPoolExecutor 构造函数来创建:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize, // 核心线程数
maximumPoolSize, // 最大线程数
keepAliveTime, // 线程空闲时间
TimeUnit.MILLISECONDS, // 时间单位
new LinkedBlockingQueue<Runnable>() // 任务队列
);
这种方式可以自定义线程池的各项参数,如核心线程数、最大线程数、线程空闲时间等,以及任务队列的类型。
方式二:通过 Executors 工具类来创建:
1.FixedThreadPool:该方法返回一个固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。
ExecutorService executor = Executors.newFixedThreadPool(nThreads);
2.SingleThreadExecutor:该方法返回一个只有一个线程的线程池。若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。
ExecutorService executor = Executors.newSingleThreadExecutor();
3.CachedThreadPool:该方法返回一个可根据实际情况调整线程数量的线程池。初始大小为 0。当有新任务提交时,如果当前线程池中没有线程可用,它会创建一个新的线程来处理该任务。如果在一段时间内(默认为 60 秒)没有新任务提交,核心线程会超时并被销毁,从而缩小线程池的大小。
ExecutorService executor = Executors.newCachedThreadPool();
4.ScheduledThreadPool:该方法返回一个用来在给定的延迟后运行任务或者定期执行任务的线程池。
ScheduledExecutorService executor = Executors.newScheduledThreadPool(corePoolSize);