线程池的好处 线程使应用程序能充分利用CPU、内存、网络等资源,然而,频繁的创建与销毁线程会浪费大量的系统资源,增加并发编程的风险。所以需要通过线程池协调多个线程,实现类似主次线程隔离、定期执行、周期执行等任务。线程池的作用包括: 利用线程池管理并复用线程,控制最大并发数 利用线程池实现任务线程队列缓存策略与拒绝机制 实现某些与时间相关的功能,如定期执行、周期执行等 隔离线程环境
Java中线程池是如何创建的? ThreadPoolExecutor 这个基础类讲起
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler ) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
几个基础概念: corePoolSize核心线程数:核心线程不会被销毁 maximumPoolSize线程池能容纳同时执行的最大线程数 keepAliveTime线程池中线程活跃的最大时间(只针对非核心线程),超过这个时间线程会被销毁,直到剩下corePoolSize个线程为止 TimeUnit:时间单位 workQueue:缓存队列,当线程数目超过核心线程数时用于保存任务的阻塞队列。阻塞队列缓存达到上限后,如果还有新任务需要处理,就创建新的线程,直到线程数=maximumPoolSize threadFactory线程工厂,用来创建线程。 为了统一在创建线程时设置一些参数,如是否守护线程,线程一些特性等,如优先级。通过这个TreadFactory创建出来的线程能保证有相同的特性。 它是一个接口类,而且方法只有一个,就是创建一个线程。 handler:拒绝策略,默认是AbortPolicy,会抛出异常。 当线程数已经达到maxPoolSize,且队列已满,会拒绝新任务。 当线程池被调用shutdown()后,会等待线程池里的任务执行完毕再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务。
|