赞
踩
Java线程池主要是用于合理创建线程,减少线程创建销毁频率(线程复用、线程资源管理),最大限度利用CPU性能。
线程池(这里说的是ThreadPoolExecutor)工作流程分3步:
1、创建线程池
2、线程池对象创建线程执行任务
3、关闭线程池
序号 | 参数名 | 参数说明 |
1 | corePoolSize | 核心线程数 |
2 | maximumPoolSize | 最大线程数 |
3 | keepAliveTime | 非核心线程空闲状态下线程回收时间 |
4 | unit | keepAliveTime 的时间单位 |
5 | workQueue | 任务队列,是一个阻塞队列,当线程数已达到核心线程数,会将任务存储在阻塞队列中 |
6 | RejectedExecutionHandler | 拒绝策略 |
ThreadPoolExecutor构造方法:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {} |
int threadNum=11; int taskNum=10; //创建一个自定义线程池对象 ThreadPoolExecutor exs = new ThreadPoolExecutor(5, threadNum, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(2)); |
corePoolSize=5 //核心线程数=5
maximumPoolSize=11 //最大线程数=11
keepAliveTime=0 //非核心线程空闲状态下线程回收时间=0
默认拒绝策略:AbortPolicy //超出后抛弃任务
线程池大小= 最大线程数 + 阻塞队列大小=11+2=13
for(int i=0;i<taskNum;i++){ //通过 ExecutorService 对象的 execute 方法将任务添加到线程去执行 exs.execute(new Runnable1()); System.out.println("---核心线程数:" + exs.getCorePoolSize()+",线程池中线程数目:"+exs.getPoolSize()+",---队列中等待执行的任务数目:"+ exs.getQueue().size()); } |
threadPoolExecutor 执行 execute 方法分下面4中情况
1)当前线程< coolPoolSize时,直接创建线程执行
当一个任务通过 submit 或者 execute 方法提交到线程池的时候,如果当前池中线程数(包括闲置线程)小于 coolPoolSize,则创建一个线程执行该任务。
2)当前线程>= coolPoolSize时,入队
如果当前线程池中线程数已经达到 coolPoolSize,则将任务放入等待队列。
3) 当前线程>= coolPoolSize,但小于maximumPoolSize时,创建非核心线程执行
如果任务不能入队,说明等待队列已满,若当前池中线程数小于 maximumPoolSize,则创建一个临时线程(非核心线程)执行该任务。
4)如果当前池中线程数已经等于 maximumPoolSize,此时无法执行该任务,根据拒绝执行策略处理。
注意:当池中线程数大于 coolPoolSize,超过 keepAliveTime 时间的闲置线程会被回收掉。回收的是非核心线程,核心线程一般是不会回收的。
如果设置 allowCoreThreadTimeOut(true),则核心线程在闲置 keepAliveTime 时间后也会被回收。
任务队列是一个阻塞队列,线程执行完任务后会去队列取任务来执行,如果队列为空,线程就会阻塞,直到取到任务。
4种拒绝策略RejectedExecutionHandler:
线程池执行任务的流程图:
exs.shutdown();
线程池有2种关闭方法:
shutdown():线程池拒接收新提交的任务,同时等待线程池里的任务执行完毕后关闭线程池。
shutdownNow() :线程池拒接收新提交的任务,同时立马关闭线程池,线程池里的任务不再执行,并能获取未被执行的任务。
- package runnable;
-
- import java.util.concurrent.*;
-
- //定义一个 Runnable接口的实现类
- class Runnable1 implements Runnable{
- @Override
- public void run() {
- try {
- System.out.println(Thread.currentThread().getName()+" 在运行任务");
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
-
- public class ThreadPoolDemo {
- public static void main(String[] args){
- int threadNum=9;
- int taskNum=10;
- //创建一个自定义线程池对象
- ThreadPoolExecutor exs = new ThreadPoolExecutor(5, threadNum, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(2));
- for(int i=0;i<taskNum;i++){
- //通过 ExecutorService 对象的 execute 方法将任务添加到线程去执行
- exs.execute(new Runnable1());
- System.out.println("---核心线程数:" + exs.getCorePoolSize()+",线程池中线程数目:"+exs.getPoolSize()+",---队列中等待执行的任务数目:"+ exs.getQueue().size());
- }
- exs.shutdown();
- }
- }
执行结果分析:
参考:https://blog.csdn.net/zhengzhaoyang122/article/details/110789385
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。