一、线程池
过于频繁的创建/销毁线程浪费性能,线程并发数量过多, JVM调度是抢占式的,线程上线文切换抢占系统资源导致阻塞。
1.线程池线程数:
一般CPU密集型:CPU+1
IO密集型:[(线程等待时间+线程CPU时间)/线程CPU时间]*CPU
2.线程池创建4种方式:
newCachedThreadPool 缓存线程池,没有线程可用就创建,空闲线程60秒未使用将被回收。
newFixedThreadPool 固定线程数,多余的任务进队列,(若需要)异常死后重新启动一个代替
newScheduledThreadPool 延迟或定期执行的线程池
newSingleThreadExecutor 单线程池,异常死后重新启动一个代替。
以上4个都是由Executors提供,底层都是由ThreadPoolExecutor实现的。
newFixedThreadPool(1)与newSingleThreadExecutor 主要区别,后者被DelegatedExecutorService装饰了,减少了很多暴露方法
3.ThreadPoolExecutor 构造参数有5/6/7个。
corePoolSize 核心线程数
maximumPoolSize 最大线程数
keepAliveTime 非核心线程数超时时长
TimeUnit 超时单位
BlockingQueue 线程池的任务对列
ThreadFactory 线程工厂 一般默认即可
RejectedExecutionHandler 拒绝策略
执行规则:
1. 线程数量未达到corePoolSize,则新建一个线程(核心线程)执行任务
2. 线程数量达到了corePools,则将任务移入队列等待
3. 队列已满,新建线程(非核心线程)执行任务
4. 队列已满,总线程数又达到了maximumPoolSize,就会抛出拒绝策略异常
5. 当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止
常用队列:
ArrayBlockingQueue :由数组结构组成的阻塞队列,可支持公平与非公平