Java程的创建非常昂费,需要VM和OS(作系统)配合完成大量的工作:
1)须为线程分配和初始化大量内存块,其中包含至少1MB的内存。
2)需要进行系统调用,以便在0S(操作系统)中创建和注册本地线程。
Jaa高并发应用频繁创建和销毁线程的操作将是非常低效的,而且是不被编程规范所允许。
如何降低Java线程的创建成本?必须使用到线程池。线程池主要解决了以下两个问题:
1)提升性能:线程池能独立负责线程的创建、维护和分配。在执行大量异步任务时,可以不需要自己创建线程,而是将任务交给线程池去调度。线程池能尽可能使用空闲的线程去执行异步任务,最大限度地对以创建的线程进行复用,使得性能明显。
2)线程管理:每个线程线程池会保持一些基本的线程统计信息,例如完成的任务数量,空闲时间等,以便对相乘进行有效的管理,使得能对所接收到的异步任务进行高效调度。
JUC的线程池架构
在多线程编程中,任务都是一些抽象且离散的工作单元,而线程是使任务异步执行的基本机制。随着应用的扩张,线程和任务管理也变得非常复杂,为了简化这些复杂的线程管理模式,我们需要一个“管理者”来统一管理线程及任务分配,这就是线程池。
在JC中有关线程池的类与接口的架构图大致如下图所示
说明:
JUC就是javutil .concurrent工具包的简称,该工具包是从JDK 1.5开始加入JDK的,是用于完成高并发、处理多线程的一个工具包。
Executor
Executor是Java异步目标任务的“执行者”接口,其目标是来执行目标任务。“执行者”Executor提供了execute()接口来执行已提交的Runnable执行目标实例。Executor作为执行者的角色,其目的是“任务提交者”与“任务执行者”分离开来的机制。它只包含一个函数式方法
void execute(Runnable command)
ExecutorService
ExecutorService继承于Executor。它是Java异步目标任务的“执行者服务”接口,对外提供异步任务的接收服务,ExecutorService提供了“接收异步任务并转交给执行者”的方法,如submit系列方法、invoke系列方法等。具体如下:
//向线程池提交单个异步任务
Future submit(Callable task);
//向线程池提交批量异步任务
List>invokeAll(Collection<?extends Callable> tasks) throws InterruptedException;
AbstractExecutorService
AbstractExecutorService是一个抽象类,它实现了ExecutorService接口。AbstractExecutorService存在的目的是为ExecutorService中的接口提供默认实现。
ThreadPoolExecutor
ThreadPoolExecutor就是大名鼎鼎的“线程池”实现类,它继承于AbstractExecutorService抽象类。
ThreadPoolExecutor是JUC线程池的核心实现类。线程的创建和终止需要很大的开销,线程池中预先提供了指定数量的可重用线程,所以使用线程池会节省系统资源,并且每个线程池都维护了-些基础的数据统计,方便线程的管理和监控。
ScheduledExecutorService
ScheduledExecutorService是一个接口,它继承于ExecutorService。它是一个可以完成“延时"
和“周期性”任务的调度线程池接口,其功能和Timer/TimerTask类似。
ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor继承于ThreadPoolExecutor,它提供了ScheduledExecutorService线程池接口中“延时执行”和“周期执行”等抽象调度方法的具体实现。
ScheduledThreadPoolExecutor类似于Timer,但是在高并发程序中,ScheduledThreadPoolExecutor的性能要优于Timer。
Executors
Executors是个静态工厂类,它通过静态工厂方法返ExecutorServiceScheduledExecutorService等线程池实例对象,这些静态工厂方法可以理解为一些快捷的创建线程池的方法