我们知道, 在Java中创建线程的代价是非常昂贵的, 需要JVM和OS的配置进行大量的处理工作:
- 必须为线程堆栈分配和初始化大量的内存块, 其中至少包含1MB的栈内存.
- 需要使用JNI系统调用, 以便在OS中创建和注册本地线程.
Java委托操作系统线程处理Java线程
一般开发中, 我们不允许频繁的创建和销毁线程, 常用的阿里开发规范Java版
不允许开发人员自行显示的创建线程, 应采用线程池减少系统资源开销.
线程池的好处
a. 提升性能
线程池能独立的负责线程的创建, 维护和分配. 在执行大量的异步任务时不需要自己创建线程, 而是交给线程池去调度. 线程池能使用空闲的线程执行异步任务, 最大限度的提高对已经创建线程的复用性, 提升性能.
b. 线程管理
每个Java线程池都有线程的管理能力. 例: 任务数量, 空闲数量, 执行时间等信息.
对线程进行有效的管理, 提升异步任务的高效调度.
Java线程池架构
1. Executor接口
异步任务的"执行者"接口, Executor提供了一个execute()来执行已经提交的Runnable执行目标实例. Executor是作为执行者的角色, 目的是提供一种将"任务提交者"和"任务执行者"分开的机制, 它只有一个函数式方法:
public interface Executor {
void execute(Runnable var1);
}
2. ExecutorService
ExecutorService接口继承自Executor, 它是异步任务的"执行者服务"接口, 对外提供异步任务的接受者服务. ExecutorService提供了接收"接收异步任务并转交给执行者"的方法.
public interface ExecutorService extends Executor {
/**
* 关闭执行器, 主要有以下特点:
* 1. 已经提交给该执行器的任务将会继续执行, 但是不再接受新任务的提交;
* 2. 如果执行器已经关闭了, 则再次调用没有副作用.
*/
void shutdown();
/**
* 立即关闭执行器, 主要有以下特点:
* 1. 尝试停止所有正在执行的任务, 无法保证能够停止成功, 但会尽力尝试(例如, 通过 Thread.interrupt中断任务, 但是不响应中断的任务可能无法终止);
* 2. 暂停处理已经提交但未执行的任务;
*
* @return 返回已经提交但未执行的任务列表
*/
List shutdownNow();
/**
* 如果该执行器已经关闭, 则返回true.
*/
boolean isShutdown();
/**
* 判断执行器是否已经【终止】.
* 仅当执行器已关闭且所有任务都已经执行完成, 才返回true.
* 注意: 除非首先调用 shutdown 或 shutdownNow, 否则该方法永远返回false.
*/
boolean isTerminated();
/**
* 阻塞调用线程, 等待执行器到达【终止】状态.
*
* @return {@code true} 如果执行器最终到达终止状态, 则返回true; 否则返回false
* @throws InterruptedException if interrupted while waiting
*/
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
/**
* 提交一个具有返回值的任务用于执行.
* 注意: Future的get方法在成功完成时将会返回task的返回值.
*
* @param task 待提交的任务
* @param 任务的返回值类型
* @return 返回该任务的Future对象
* @throws RejectedExecutionException 如果任务无法安排执行
* @throws NullPointerException if the task is null
*/
Future submit(Callable task);
/**
* 提交一个 Runnable 任务用于执行.
* 注意: Future的get方法在成功完成时将会返回给定的结果(入参时指定).
*
* @param task 待提交的任务
* @param result 返回的结果
* @param 返回的结果类型
* @return 返回该任务的Future对象
* @throws RejectedExecutionException 如果任务无法安排执行
* @throws NullPointerException if the task is null
*/
Future submit(Runnable task, T result);
/**
* 提交一个 Runnable 任务用于执行.
* 注意: Future的get方法在成功完成时将会返回null.
*
* @param task 待提交的任务
* @return 返回该任务的Future对象
* @throws RejectedExecutionException 如果任务无法安排执行
* @throws NullPointerException if the task is null
*/
Future> submit(Runnable task);
/**
* 执行给定集合中的所有任务, 当所有任务都执行完成后, 返回保持任务状态和结果的 Future 列表.
*
* 注意: 该方法为同步方法. 返回列表中的所有元素的Future.isDone() 为 true.
*
* @param tasks 任务集合
* @param 任务的返回结果类型
* @return 任务的Future对象列表,列表顺序与集合中的迭代器所生成的顺序相同,
* @throws InterruptedException 如果等待时发生中断, 会将所有未完成的任务取消.
* @throws NullPointerException 任一任务为 null
* @throws RejectedExecutionException 如果任一任务无法安排执行
*/
List> invokeAll(Collection extends Callable> tasks) throws InterruptedException;
/**
* 执行给定集合中的所有任务, 当所有任务都执行完成后或超时期满时(无论哪个首先发生), 返回保持任务状态和结果的 Future 列表.
*/
List> invokeAll(Collection extends Callable> tasks, long timeout, TimeUnit unit) throws InterruptedException;
/**
* 执行给定集合中的任务, 只有其中某个任务率先成功完成(未抛出异常), 则返回其结果.
* 一旦正常或异常返回后, 则取消尚未完成的任务.
*/
T invokeAny(Collection extends Callable> tasks) throws InterruptedException, ExecutionException;
/**
* 执行给定集合中的任务, 如果在给定的超时期满前, 某个任务已成功完成(未抛出异常), 则返回其结果.
* 一旦正常或异常返回后, 则取消尚未完成的任务.
*/
T invokeAny(Collection extends Callable> tasks, long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
3. AbstractExecutorService
AbstractExecutorService是一个抽象类, 它实现了ExecutorService接口.
AbstractExecutorService存在的目的是为ExecutorService中的接口提供默认实现
4. ThreadPoolExecutor *
JDK所有线程池实现的父类, 它继承于AbstractExecutorService抽象类.
ThreadPoolExecutor是JUC线程池的核心实现类. 线程的创建和终止需要很大的开销, 线程池中预先提供了指定数量的可重用线程, 所以使用线程池会节省系统资源, 并且每个线程池都维护了一些基础的数据统计, 方便线程的管理和监控.
5. ScheduledExecutorService
ScheduledExecutorService是一个接口, 它继承于ExecutorService. 它是一个可以完成“延时”和“周期性”任务的调度线程池接口, 其功能和Timer/TimerTask类似.
[Timer]Java定时工具类
6. ScheduledThreadPoolExecutor
继承于ThreadPoolExecutor, 它提供了ScheduledExecutorService线程池接口中"延时执行"和"周期执行"等抽象调度方法的具体实现. 类似于Timer, 但是在高并发程序中, ScheduledThreadPoolExecutor的性能要优于Timer.
7. Executors
Executors是一个静态工厂类, 它通过静态工厂方法返回ExecutorService, ScheduledExecutorService等线程池示例对象, 这些静态工厂方法可以理解为一些快捷的创建线程池的方法.