JAVA线程池
为什么用线程池
线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量超出数量的线程排队等候,等其它线程执行完毕,再从队列中取出任务来执行。他的主要特点为∶线程复用;控制最大并发数;管理线程。
- 第一∶降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 第二∶提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
- 第三∶提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控
线程池基本知识
架构说明
Java 中的线程池是通过Executor框架实现的,该框架中用到了Executor,Executors,ExecutorService, ThreadPoolExecutor这几个类。
类比其他工具类如Arrays,Collections,线程池的工具类是Executors。
JDK提供的五种线程池
支持的线程池种类五种,除了java8新出的Executors.newWorkStealingPool()底层是ForkJoinPool,其他四个底层都是ThreadPoolExecutor。
//需指定线程数量,一池固定多线程,适用于执行长期任务
Executors.newFixedThreadPool(10);
//一池一线程,适用于执行单个任务
Executors.newSingleThreadExecutor();
//一池多线程,自动扩容,适用于大量短期异步小任务,负载轻的服务
Executors.newCachedThreadPool();
//调度带时间
Executors.newScheduledThreadPool(10);
//java8 新出
Executors.newWorkStealingPool();
Executors.newFixedThreadPool()
- 构造源码:
/**
* Creates a thread pool that reuses a fixed number of threads
* operating off a shared unbounded queue. At any point, at most
* {@code nThreads} threads will be active processing tasks.
* If additional tasks are submitted when all threads are active,
* they will wait in the queue until a thread is available.
* If any thread terminates due to a failure during execution
* prior to shutdown, a new one will take its place if needed to
* execute subsequent tasks. The threads in the pool will exist
* until it is explicitly {@link ExecutorService#shutdown shutdown}.
*
* @param nThreads the number of threads in the pool
* @return the newly created thread pool
* @throws IllegalArgumentException if {@code nThreads <= 0}
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
- 主要特点如下∶
- 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
- newFixedThreadPool创建的线程池corePoolSize和maximumPoolSize值是相等的,它使用的LinkedBlockingQueue;
- 代码示例:
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
try {
//threadPool.submit(); //用于执行带返回值的任务
//threadPool.execute();
// 模拟10个线程需要执行
for (int i = 0; i < 10; i++) {
fixedThreadPool.execute(()->{
System.out.println(Thread.currentThread()