目录
线程池顾名思义就是类似一个“池子”里边存着线程,我们需要处理任务的时候就从中取出一个线程,搭载上我们的任务去执行就好了。那为什么要有线程池呢?
看到这里线程池的作用已经很明显了:减少每次启动,销毁线程的损耗。
我们先介绍其中一些参数的意义:
1、corePollSize:核心线程最大数量,可以理解为正式员工,一般来说,正式员工不会被解雇(销毁),但当 allowCoreThreadTimeout 设为 true 时,正式员工摸鱼时长超过 keepAliveTime(下边会讲)也会被销毁。
2、maximumPollSize:线程池中 正式员工 + 临时工 的最大数量,这是我们线程池中最多的线程数,一旦达到这个数值,后序任务就会阻塞
3、keepAliveTime:员工摸鱼时长,如果临时工超过摸鱼时长都没有分配任务,临时工就会被解雇(销毁),当然,如果 allowCoreThreadTimeout 设置为true,正式工摸鱼达到时长也会被解雇
4、unit:unit 其实是keepAliveTime 的时间单位
5、workQueue: 任务队列(本质上就是阻塞队列),存的是可执行的对象
6、threadFactory:线程工厂,我们可以介入到如何招聘员工(创建线程的方式)
7、handler:拒绝策略,有四种拒绝策略,后边会详细说明
首先上图:
可以看到图很难看懂,下边是针对流程的梳理:
我们在线程池加入一个任务时,如果正式员工的数量还没到上限,我们就优先招一个正式工去执行任务,如果正式工满了,我们就去看阻塞队列满没满,优先把任务放到阻塞队列中,如果此时阻塞队列也满了,我们就只能招聘临时工去执行任务,如果员工总的数量都满了,我们就只能采取拒绝策略了。
在每个临时工执行完自己的任务后,我们都要看它是不是长时间摸鱼,以此回收它,当然,如果设置了 allowCoreThreadTimeout 那么正式员工摸鱼也会被解雇。
当线程池的 员工总数 达到最大值,此时如果还有新来的任务,我们就要采用拒绝策略,拒绝策略有四种
1、AbortPolicy:直接抛异常
2、CallerRunsPolicy:谁添加任务谁自己做(自己动手丰衣足食)
3、DiscardPolicy:丢弃任务,不抛异常。(谁也不知道)
3、DiscardOlderstPolicy:丢弃队列中最早的未处理任务,执行新任务
Excutors创建线程的几种方式:
newFixedThreadPoll:创建固定线程数的线程池
newCachedThreadPoll:创建线程数目动态增长的线程池
newSingleThreadExcutor:创建只包含单个线程的线程池
newScheduledThreadPoll:设定延迟时间后执行命令
- import java.util.ArrayList;
- import java.util.List;
- import java.util.concurrent.BlockingQueue;
- import java.util.concurrent.LinkedBlockingQueue;
-
- public class ThreadDemo2 {
-
- static class Worker extends Thread{
- private BlockingQueue<Runnable> queue = null;
-
- public Worker(BlockingQueue<Runnable> queue){
- this.queue = queue;
- }
- @Override
- public void run() {
- while (true){
- try {
- Runnable command = queue.take();
- command.run();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- static class ThreadPool{
- // 阻塞队列 用来组织任务
- private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
-
- // 用来存放当前的工作线程
- private List<Worker> workers = new ArrayList<>();
-
- // 最大工作线程数
- private final int MAX_WORKER_COUNT = 10;
-
- public void submit(Runnable command) throws InterruptedException {
- if(workers.size() < MAX_WORKER_COUNT){
- // 当前工作线程不足 创建新的线程
- // Worker内部需要获取到队列的内容,就需要创建一个构造方法.
- Worker worker = new Worker(queue);
- worker.start();
- workers.add(worker);
- }
- queue.put(command);
- }
- }
-
- public static void main(String[] args) throws InterruptedException {
- ThreadPool pool = new ThreadPool();
- pool.submit(new Runnable() {
- @Override
- public void run() {
- System.out.println("hello");
- }
- });
- }
- }
-