线程池
优势:
- 提⾼线程的利⽤率
- 提⾼响应速度
- 便于统⼀管理线程对象
- 可控制最⼤并发数
线程池的具体设计思想:
- 核⼼池的⼤⼩
- 线程池的最⼤容量
- 等待队列
- 拒绝策略
线程池启动的时候会按照核⼼池的数来创建初始化的线程对象 2 个。
开始分配任务,如果同时来了多个任务, 2 个线程对象都被占⽤了,第 3 个以及之后的任务进⼊等待队列,当前有线程完成任务恢复空闲状态的时候,等待队列中的任务获取线程对象。
如果等待队列也占满了,⼜有新的任务进来,需要去协调,让线程池再创建新的线程对象,但是线程池不可能⽆限去创建线程对象,⼀定会有⼀个最⼤上限,就是线程池的最⼤容量。
如果线程池已经达到了最⼤上限,并且等待队列也占满了,此时如果有新的任务进来,只能选择拒绝,并且需要根据拒绝策略来选择对应的⽅案。
ThreadPoolExecutor
直接实例化 ThreadPoolExecutor ,实现定制化的线程池,⽽不推荐使⽤ Executors 提供的封装好的⽅法,因为这种⽅式代码不够灵活,⽆法实现定制化。
ThreadPoolExecutor 核⼼参数⼀共有 7 个
- corePoolSize:核⼼池的⼤⼩
- maximumPoolSize:线程池的最⼤容量
- keepAliveTime:线程存活时间(在没有任务可执⾏的情况下),必须是线程池中的数量⼤于 corePoolSize,才会⽣效
- TimeUnit:存活时间单位
- BlockingQueue:等待队列,存储等待执⾏的任务
- ThreadFactory:线程⼯⼚,⽤来创建线程对象
- RejectedExecutionHandler:拒绝策略
1、AbortPolicy:直接抛出异常
2、DiscardPolicy:放弃任务,不抛出异常
3、DiscardOldestPolicy:尝试与等待队列中最前⾯的任务去争夺,不抛出异常
4、CallerRunsPolicy:谁调⽤谁处理
线程池 3 ⼤考点
1、Executors ⼯具类的 3 种实现
ExecutorService executorService = Executors.newSingleThreadExecutor();
ExecutorService executorService = Executors.newFixedThreadPool(5);
ExecutorService executorService = Executors.newCachedThreadPool();
2、7 个参数
- corePoolSize:核⼼池的⼤⼩
- maximumPoolSize:线程池的最⼤容量
- keepAliveTime:线程存活时间(在没有任务可执⾏的情况下),必须是线程池中的数量⼤于 corePoolSize,才会⽣效
- TimeUnit:存活时间单位
- BlockingQueue:等待队列,存储等待执⾏的任务
- ThreadFactory:线程⼯⼚,⽤来创建线程对象
- RejectedExecutionHandler:拒绝策略
3、4 种拒绝策略
1、AbortPolicy:直接抛出异常
2、DiscardPolicy:放弃任务,不抛出异常
3、DiscardOldestPolicy:尝试与等待队列中最前⾯的任务去争夺,不抛出异常
4、CallerRunsPolicy:谁调⽤谁处理