Java线程池类其实是来自JUC包的一个分支,这篇文章接上一篇JUC的详解。
在多线程的并发编程中,如果碰到线程数量非常多,并且每个线程都结束的很快,这样一来,频繁创建线程和销毁线程的时间,可能比线程真实工作的时间还要长,如果是这样的话,那么程序工作的效率就会很低,针对这样一种情况,Java中就设计了线程池,用来解决这个问题,线程池可以通过保留线程复用来解决这种效率低下的问题。
在JUC包中有一个java.uitl.concurrent.ThreadPoolExecutor类,这个类是实现线程池最核心的类,我们看看ThreadPoolExecutor的构造函数,线程池的参数是面试中最常问的一个问题,那么了解有哪些参数,构造函数就是我们必须看的了,在下面几个苟傲函数中,有几个参数比较重要。
1.corePoolSize从字面意思上也能看出,这是核心池的大小。其实就是可以容纳的线程大小,在线程池中的数量超过这个数时,其他线程来了就放到缓存队列中等待执行。
2.maximumPoolSize,线程池最大线程数,这个参数也很重要,表示线程池中最多可以创建多少个线程,在最后一个构造函数我们可以看到,maximumPoolSize肯定得比corePoolSize大,max是包括core加排队的数量,所以如果比core小的话,会报异常。
3.keepAliveTime:表示线程如果没有任务执行对多保存多少时间会终止,这样就防止有些线程在执行完任务后如果不需要了,就不会一直保持存活的状态占用资源。
4.unit:参数keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性:
5.workQueue:阻塞队列,用来储存等待执行的任务,其中的BlockingQueue也是JUC包中的并发容器类型。
6.threadFactory:线程工厂,主要用来创建线程的
TimeUnit.DAYS; //天
TimeUnit.HOURS; //小时
TimeUnit.MINUTES; //分钟
TimeUnit.SECONDS; //秒
TimeUnit.MILLISECONDS; //毫秒
TimeUnit.MICROSECONDS; //微妙
TimeUnit.NANOSECONDS; //纳秒
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue 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.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
具体线程池的实现可以看看这篇文章