一. 线程池简介
1. 线程池的概念:
线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。
2. 线程池的工作机制
2.1 在线程池的编程模式下,任务是提交给整个线程池,而不是直接提交给某个线程,线程池在拿到任务后,就在内部寻找是否有空闲的线程,如果有,则将任务交给某个空闲的线程。
2.1 一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。
3. 使用线程池的好处
Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池。在开发过程中,合理地使用线程池能够带来3个好处:
第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
第三:提高线程的可管理性。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。但是,要做到合理利用线程池,必须对其实现原理了如指掌。
二:JDK对线程池的支持
JDK提供的Executor框架
JDK提供了Executor框架,可以让我们有效的管理和控制我们的线程,其实质也就是一个线程池。Executor下的接口和类继承关系如下:
Executors:提供了一系列静态工厂方法用于创建各种线程池
其中常用几类如下:
public staticExecutorService newFixedThreadPool()public staticExecutorService newSingleThreadExecutor()public staticExecutorService newCachedThreadPool()public staticScheduledExecutorService newSingleThreadScheduledExecutor()public static ScheduledExecutorService newScheduledThreadPool()
1、newFixedThreadPool:该方法返回一个固定线程数量的线程池;
2、newSingleThreadExecutor:该方法返回一个只有一个现成的线程池;
3、newCachedThreadPool:返回一个可以根据实际情况调整线程数量的线程池;
4、newSingleThreadScheduledExecutor:该方法和newSingleThreadExecutor的区别是给定了时间执行某任务的功能,可以进行定时执行等;
5、newScheduledThreadPool:在4的基础上可以指定线程数量。
创建线程池实质调用的还是ThreadPoolExecutor
在Executors类中,我们拿出来一个方法简单分析一下:
可以看出,类似的其他方法一样,在Executors内部创建线程池的时候,实际创建的都是一个ThreadPoolExecutor对象,只是对ThreadPoolExecutor构造方法,进行了默认值的设定。ThreadPoolExecutor的构造方法如下:
参数含义如下:
1、corePoolSize 核心线程池大小;
2、maximumPoolSize 线程池最大容量大小;
3、keepAliveTime 线程池空闲时,线程存活的时间;
4、TimeUnit 时间单位;
5、ThreadFactory 线程工厂;
6、BlockingQueue任务队列;
7、RejectedExecutionHandler 线程拒绝策略;
Executor框架实例
1、实例一:
public classThreadPoolDemo {public static voidmain(String[] args) {
ExecutorService executorService= Executors.newFixedThreadPool(4);for (int i = 0; i < 10; i++) {int index =i;
executorService.submit(()-> System.out.println("i:" + index +
" executorService"));
}
executorService.shutdown();
}
}
submit(Runnable task)方法提交一个线程。
但是使用最新的“阿里巴巴编码规范插件”检测一下会发现:
线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,
这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors各个方法的弊端:
1)newFixedThreadPool和newSingleThreadExecutor