1.引言
提到线程池,我们可以先了解相似的常量池:字符串常量,在Java程序最初构建的时候,就已经准备好,等程序运行的时候,这样的常量就直接加载到内存中,只剩下构造和销毁的开销。
1.1线程池的优点
同理,线程池就是为了高效地创建销毁线程
最初引入线程池的原因——频繁创建销毁进程,太慢了。
现在随着对性能要求更进一步,无法接受频繁创建销毁进程的开销
线程池相当于 把线程提前创建好,放到一个地方(类似于一个数组),可以随时取用 随时放回
1.2线程池的具体表现
提出问题 为什么认为,直接创建线程的开销 比从线程池取用 线程更大呢
一个操作系统 = 内核(内核态) + 配套的应用程序(用户态)
其中内核包含操作系统的各种核心功能(管理硬件设备,给软件提供稳定的运行环境)
一个操作系统,内核就是一份,一份内核,要给所有的应用程序提供服务支持
例如:在银行中
当用户想要取 复印 证件照 面对两个选择
- 交给内核完成——过程不可控,不一定立刻执行
- 前往自助复印机——过程可控,立即执行
如果有一段代码是应用程序中自行完成的——整个执行过程是可控的
如果有一段代码,需要进入内核,由内核完成一系列的工作,这个过程是不可控的,程序员写的代码无法干预
因此,通常认为,可控的过程比不可控的过程要更高效
从线程池取已有的线程,纯应用程序代码就可以完成【可控】
从操作系统创建新线程,就需要操作系统内核配合完成【不可控】
使用线程池,可以节省 应用程序切换到内核中运行 这样的开销
2.Java标准库中的线程池
2.1 ThreadPollExecutor
线程池里准备好一些线程,让这些线程执行一些任务
其核心方法是 submit(Runnable)
- 通过Runnable 描述一段要执行的任务
- 通过submit任务 放入 到线程池中
此时线程池里的线程就会执行这样的任务
2.2构造方法及其参数含义

由于上述ThreadPoolExecutor 比较复杂,于是Java标准库,也提供了另一组类,
进一步封装ThreadPoolExecutor,简化线程池的使用(也是基于工厂模式)
——提供线程池工厂类Executors
Executors.newFixedThreadPool(n); 创建固定线程池:核心线程数=最大线程数=nExecutors.newCachedThreadPool(); 创建无线线程数 最大线程数是一个很大的数字(线程可以无限增加)以上返回结果类型 均为 ExecutorService


至少创建了几十个线程
注意:在 阿里巴巴Java编程规范手册中 提到:
明确表示使用线程池,要使用ThreadPoolExecutor这个版本,而不应该使用Executors
理由:使用Executors 线程数目/拒绝策略 等信息是隐式的 不好控制(创建200多个线程,确实不是一件好事)
2405

被折叠的 条评论
为什么被折叠?



