每一个方法都是一个任务,Runnable的run方法也不例外。正常情况这些任务都是交给主线程按顺序执行。而Runnable的start方法可以调用系统开辟一条新的线程,用来执行Runnable先的run方法任务。而且一个start只能唤起一个线程执行run方法(就是执行Runnable的实现对象)。
线程池的使用可以理解为一个任务调度管理工具,创建一个个的Runnable实现对象(任务),不在需要自己去执行start方法调用线程执行任务,而线程池有一套自己的线程创建和执行方式。
线程池使用了Exeutor框架来实现。
该框架用到的核心类
Executor,Executors,ExecutorService,ThreadPoolExecutor,Callable,Future,FutureTask 这几个核心类
类图之间的关系
ThreadPoolExecutor 中的构造方法通过传入不同的参数而构建不同的线程池
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler){
}
参数说明:
①corePoolSize:线程池的核心线程数,说白了就是,即便是线程池里没有任何任务,也会有corePoolSize个线程在候着等任务。
②maximumPoolSize:最大线程数,不管你提交多少任务,线程池里最多工作线程数就是maximumPoolSize。
③keepAliveTime:线程的存活时间。当线程池里的线程数大于corePoolSize时,如果等了keepAliveTime时长还没有任务可执行,则线程退出。
⑤unit:这个用来指定keepAliveTime的单位,比如秒:TimeUnit.SECONDS。
⑥workQueue:一个阻塞队列,提交的任务将会被放到这个队列里。
⑦threadFactory:线程工厂,用来创建线程,主要是为了给线程起名字,默认工厂的线程名字:pool-1-thread-3。
⑧handler:拒绝策略,当线程池里线程被耗尽,且队列也满了的时候会调用。
线程池的工作流程
线程池的拒绝策略:
常用的四个: AbortPolicy, CallerRunsPolicy,DiscardOldestPolicy,DiscardPolicy 。
自定义的实现RejectedExecutionHandler 接口即可。