线程池是一种多线程技术,最大限度的提高cpu的利用率,提升系统的运行效率。然而线程的创建和销毁是十分消耗系统资源和时间的,线程池的作用在于集中管理线程的创建和销毁以及实现线程的复用。
1.ThreadPoolExecutor的核心构造方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
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;
}
关键参数解析
corePoolSize:核心线程数,类似于公司的骨干员工
maximumPoolSize:最大线程数,任务太多后,招聘的新员工
keepAliveTime:线程空闲时的存活时间
unit:时间单位
workQueue:任务队列,开发的项目
threadFactory:创建线程的工厂类
handler:拒绝策略
2.线程池工作流程
ThreadPoolExecutor#execute方法为入口:
1)接受到任务后,先判断当前线程数是否小于核心线程数,如果小于则创建线程并执行任务。否则进入步骤2。
2)判断当前任务是否能够添加到任务队列中,如果能则添加到队列,等待线程执行。如果不能则执行步骤3。
3)判断当前线程数是否大于允许的最大线程数,如果小于则创建线程并执行任务,否则执行步骤4。
4)执行拒绝策略,拒绝任务。
3.关键方法解析
ThreadPoolExecutor#execute为主流程方法
ThreadPoolExecutor#addWorker创建新的线程并执行任务。
线程启动。
ThreadPoolExecutor#runWorker执行任务。
ThreadPoolExecutor#getTask获取任务。
4.简单使用线程池
newSingleThreadExecutor:只有一个线程,任务队列为Integer.MAX_VALUE。
newCachedThreadPool:最大线程数为Integer.MAX_ VALUE。
newFixedThreadPool:线程数固定,任务队列为Integer.MAX_ VALUE。
场景:比如接受到异步通知后立即响应,内部逻辑可以使用线程池完成。也可使用mq完成。
class ThreadPoolTest {
public static void main(String[] args) {
// ExecutorService executor = Executors.newSingleThreadExecutor();
// ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newCachedThreadPool();
// ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(5);
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(5));
for (int i = 0; i < 16; i++) {
MyTask myTask = new MyTask(i);
executor.execute(myTask);
System.out.println("线程池中线程数目:" + executor.getPoolSize() + ",队列中等待执行的任务数目:" +
executor.getQueue().size() + ",已执行玩别的任务数目:" + executor.getCompletedTaskCount());
}
executor.shutdown();
}
}
class MyTask implements Runnable {
private int taskNum;
public MyTask(int num) {
this.taskNum = num;
}
@Override
public void run() {
System.out.println("正在执行task " + taskNum);
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task " + taskNum + "执行完毕");
}
}