创建方式
- Executors.newWorkStealingPool();
- 创建一个具有抢占式操作的线程池
- Executors.newScheduledThreadPool(10)
- 创建一个定长线程池,支持定时及周期性任务执行。
- Executors.newFixedThreadPool(10)
- 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
- Executors.newSingleThreadExecutor()
- 按顺序来执行线程任务 但是不同于单线程,这个线程池只是只能存在一个线程,这个线程死后另外一个线程会补上,继续按顺序执行任务。
- Executors.newCachedThreadPool()
- 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。线程池为无限大
7大参数
- int corePoolSize:核心线程数
- int maximumPoolSize:最大线程数
- long keepAliveTime:空闲时间
- TimeUnit unit:时间单位
- BlockingQueue<Runnable> workQueue:阻塞队列
- ThreadFactory threadFactory:线程工厂类
- RejectedExecutionHandler handler:拒绝策略
线程池处理流程
拒绝策略
jdk的内置拒绝策略:
创建线程必须使用线程池创建
线程池不允许使用Executors创建,因为线程最大数设置的是Integer.MAX_VALUE = 21E+,无线的创建线程可能造成OOM
使用ThreadPoolExecutor创建线程池:
# ThreadPoolExecutor
ExecutorService threadPool = new ThreadPoolExecutor(0, 10,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
# Executors
ExecutorService threadPool = Executors.newCachedThreadPool();
手写线程池
public static void main(String[] args) {
ExecutorService threadPool = new ThreadPoolExecutor(
2,// 线程核心数
5, // 最大线程数
1L, // 线程空闲时间
TimeUnit.SECONDS, // 时间单位
new LinkedBlockingDeque<Runnable>(3), // 阻塞队列,要设置队列大小,默认是Integer.MAX_VALUE
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略
try {
for (int i = 0; i < 10; i++) {
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName());
});
}
} catch (Exception e){
e.printStackTrace();
} finally {
threadPool.shutdown();
}
}
最大线程数量该如何配置
1、CPU密集型
CPU核数+1
Runtime.getRuntime().availableProcessors()+1
2、IO密集型
- 第一种:由于IO密集型任务线程并不是一支在执行任务则应配置尽可能多的线程,例如CPU核数 * 2
Runtime.getRuntime().availableProcessors() * 2
- 第二种: