线程池之ThreadPoolExecutor概述
作者:互联网
ThreadPoolExecutor提供了四个构造方法:
我们以最后一个构造方法(参数最多的那个),对其参数进行解释:
public ThreadPoolExecutor(int corePoolSize, // 1 int maximumPoolSize, // 2 long keepAliveTime, // 3 TimeUnit unit, // 4 BlockingQueue<Runnable> workQueue, // 5 ThreadFactory threadFactory, // 6 RejectedExecutionHandler handler ) { //7 if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
序号 | 名称 | 类型 | 含义 |
---|---|---|---|
1 | corePoolSize | int | 核心线程池大小 |
2 | maximumPoolSize | int | 最大线程池大小 |
3 | keepAliveTime | long | 线程最大空闲时间 |
4 | unit | TimeUnit | 时间单位 |
5 | workQueue | BlockingQueue<Runnable> | 线程等待队列 |
6 | threadFactory | ThreadFactory | 线程创建工厂 |
7 | handler | RejectedExecutionHandler | 拒绝策略 |
自定义线程池:
public class ThreadPoolTest { public static void main(String[] args) throws IOException { int corePoolSize = 2;// 核心线程大小 int maximumPoolSize = 4;// 最大线程池大小 long keepAliveTime = 10; // 线程空闲10s后自动结束 TimeUnit unit = TimeUnit.SECONDS; // ArrayBlockingQueue,该阻塞队列底层维护了一个定长数组(创建对象必须指定容量) BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2); ThreadFactory threadFactory = new NameTreadFactory();// 自定义线程工厂 RejectedExecutionHandler handler = new MyIgnorePolicy(); // 自定义拒绝策略 // handler = new ThreadPoolExecutor.AbortPolicy();// 无法处理新任务会抛出RejectedExecutionException异常 // 创建线程池对象 ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); executor.prestartAllCoreThreads(); // 预启动所有核心线程 // 创建10个任务对象提交到线程池中 for (int i = 1; i <= 10; i++) { MyTask task = new MyTask(String.valueOf(i)); executor.execute(task); } System.in.read(); //阻塞主线程 } // 任务对象 static class MyTask implements Runnable { private String name; public MyTask(String name) { this.name = name; } @Override public void run() { try { System.out.println(this.toString() + " is running!"); Thread.sleep(3000); //让任务执行慢点 } catch (InterruptedException e) { e.printStackTrace(); } } public String getName() { return name; } @Override public String toString() { return "MyTask [name=" + name + "]"; } } // 自定义拒绝策略 static class MyIgnorePolicy implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { doLog(r, executor); } private void doLog(Runnable r, ThreadPoolExecutor e) { // 可做日志记录等 System.err.println(r.toString() + " rejected"); // System.out.println("completedTaskCount: " + e.getCompletedTaskCount()); } } // 线程工厂类 static class NameTreadFactory implements ThreadFactory { private final AtomicInteger mThreadNum = new AtomicInteger(1); @Override public Thread newThread(Runnable r) { Thread t = new Thread(r, "my-thread-" + mThreadNum.getAndIncrement()); System.out.println(t.getName() + " has been created"); return t; } } }
输出结果如下:
该线程池同一时间最多处理4个任务,2个任务处于等待对列中,其余的任务都会被拒绝执行。
线程池的处理流程主要分为3步:
- 当在execute(Runnable)方法中提交的新任务后,线程池先判断线程数是否达到了核心线程数(corePoolSize)。如果未达到线程数,则创建核心线程处理任务;否则,就执行下一步;
- 接着线程池判断任务队列是否满了。如果没满,则将任务添加到任务队列中;否则,执行下一步;
- 接着因为任务队列满了,线程池就判断线程数是否达到了最大线程数。如果未达到,则创建非核心线程处理任务;否则,就执行饱和策略,默认会抛出RejectedExecutionException异常。
setCorePoolSize
和setMaximumPoolSize
进行动态更改。
标签:corePoolSize,maximumPoolSize,int,任务,概述,线程,ThreadPoolExecutor 来源: https://www.cnblogs.com/godzzz/p/15963247.html