在《阿里巴巴Java手册》里有一条,
简单来说使用线程池有以下目的
- 线程是稀缺资源,不宜频繁的创建
- 解耦:线程的创建与执行完全分开,方便维护
- 应当将其放入一个池子中,可以给其他任务进行复用
线程池原理
池化技术,最核心的思想就是把宝贵的资源放到一个池子中;每次使用都从里面获取,用完之后又放回池子供其他人使用,有点吃大锅饭的意思。
常见的创建线程池的方式:
Executors.newCachedThreadPool():无限线程池。
Executors.newFixedThreadPool(nThreads):创建固定大小的线程池。
Executors.newSingleThreadExecutor():创建单个线程的线程池。
但通过这三种方式创建的源码就会发现:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
实际上还是利用 ThreadPoolExecutor
类实现的
首先是创建线程的API
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
- corePoolSize 线程池的基本大小
- maximumPoolSize 线程池最大线程大小
- keepAliveTime 和 unit 线程空闲后的存活时间
- workQueue 存放任务的阻塞队列
- handler 当队列和最大线程池都满了之后的饱和策略
在 ThreadPoolExecutor 类中有几个非常重要的方法
execute()//通过这个方法向线程池提交一个任务,交由线程池去执行
submit()//能够返回任务执行的结果
shutdown()
shutdownNow()//二者都用来关闭线程池