一.为什么要使用线程池
1)降低系统资源得消耗,重复创建和销毁线程将消耗系统资源
2)通过线程池有效的管理线程,避免无限制地创建线程
3)可以创建定时或延时任务
二.线程池的主要参数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
1.corePoolSize(核心线程数):
核心线程会一直存活,设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭;
当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建线程来执行任务;
2.maximumPoolSize(最大线程数):
当线程数大于corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务;
当线程数等于maximumPoolSize,且任务队列已满时,线程池会根据拒绝策略来处理任务;
3.keepAliveTime(线程存活保持时间):
当线程池中线程数大于核心线程数时,线程的空闲时间如果超过线程存活时间,那么这个线程就会被销毁,直到线程池中的线程数小于等于核心线程数。
4.unit(存活时间单位)
5.workQueue(任务队列):
用于传输和保存等待执行任务的阻塞队列。
6.threadFactory(线程工厂):
用于创建新线程。threadFactory创建的线程也是采用new Thread()方式,threadFactory创建的线程名都具有统一的风格:pool-m-thread-n(m为线程池的编号,n为线程池内的线程编号)
7.handler(线程饱和策略):
当线程池和队列都满了,再加入线程会执行此策略。
三.线程池执行流程
四.工作队列
1.直接提交:默认选项,SynchronousQueue,将任务直接提交给线程而不保持他们,需要注意的是,根据配置的maximumPoolSizes触发拒绝策略;
2.无界队列:LinkedBlockingQueue,此策略导致线程池最大创建的线程为核心线程数,因为队列太大,可能会导致内存溢出;
3.有界队列:ArrayBlockingQueue,最大线程数的配置将会觉得是否触发拒绝策略
五.ThreadFactory
static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
1.自定义具有描述意义的线程名称。如果使用默认的ThreadFactory,它给线程起名字大概规律就是pool-.m-thread-n
2.设置线程是否是守护线程,默认的ThreadFactory总是提交非守护线程。
3.设置线程优先级,默认ThreadFactory总是提交的一般优先级线程。
六.拒绝策略
1.CallerRunsPolicy(直接运行run方法):
线程调用运行该任务的 execute 本身。此策略提供简单的反馈控制机制,能够减缓新任务的提交速度。
2.AbortPolicy(抛异常):
直接抛出运行时异常RejectedExecutionException
3.DiscardPolicy(直接丢弃):
不能执行的任务将被删除,不抛出异常
4.DiscardOldestPolicy(抛弃最老的线程):
如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,将此任务入队