线程池
1.概念
概念:使用池化技术来管理和使用线程的技术,就叫做线程池。
线程池里面包含的重要内容:
- 线程
- 任务队列
2.为什么要使用线程池?
2.1线程的缺点
- 线程的创建需要开辟内存资源:本地方法栈、虚拟机程序计数器等线程私有变量的内存频繁的创建和消耗会带来一定的性能开销
- 使用线程不能很友好的管理任务和友好的拒绝任务
- 强制:线程资源必须使用线程池创建,不允许在应用中字形显示创建线程
2.2使用线程池的原因
创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。从JDK1.5开始,Java API提供了Executor框架让你可以创建不同的线程池。比如单线程池,每次处理一个任务;数目固定的线程池或者是缓存线程池(一个适合很多生存期短的任务的程序的可扩展线程池)。
3.线程池的创建方法
线程池的创建总共有7种2类,JDK1.8之后为7种,在此之前为5~6种。
3.1创建固定个数的线程
public class Test01 {
public static void main(String[] args) {
//创建固定个数的线程池(来自juc包)
ExecutorService executorService = Executors.newFixedThreadPool(5);
//不用start,只需设置任务,自动执行
for (int i = 0; i < 10; i++) {
//设置任务
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println("线程名:" + Thread.currentThread().getName());
}
});
}
}
}
- 经典面试题:创建10个线程来执行2个任务,问创建了几个线程?
答:2个,线程池是懒加载的,是经过优化后的。任务数小于线程数,会新启线程数。
- 线程池的执行流程:当拿到一个任务后,会判断当前线程池里面的线程数量是否达到最大值,如果没有达到创建新的线程执行任务;如果线程池的数量已经是最大值,并且没有空闲线程,当前的任务会被放到线程池中的任务队列中,等待执行。
3.2创建带缓存的线程池
public class Test03 {
public static void main(String[] args) {
//创建带缓存的线程池(不用传参)
ExecutorService service = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++)