如何正确使用Java线程池

线程池创建

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

corePoolSize: 核心线程数

maximumPoolSize:池中允许最大线程数

keepAliveTime:当线程数大于核心线程数据时,多余空闲线程在终止之前等待新任务的最长时间

unit:参数keepAliveTime的单位

workQueue:用于保留任务的队列,此队列仅保存由execute方法提交的任务

threadFactory:创建新线程的工厂类

handler:当达到最大线程数和工作队列满时的处理类

通过源码可以看到

  • 当传入corePoolSize<0,maximumPoolSize<=0,maximumPoolSize < corePoolSize,keepAliveTime < 0时会抛出new IllegalArgumentException()
  • 传入workQueue == null,threadFactory == null , handler == null时,抛出new NullPointerException()

样例

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.*;

/**
 * @author liujun
 */
public class ThreadDemo {

    public static void main(String[] args) {
        //创建一个工作队列最大10容量
        BlockingQueue<Runnable> weekQueue = new LinkedBlockingQueue<>(10);
        //创建一个线程创建工程
        ThreadFactory threadFactory = new ThreadFactoryBuilder()
            .setNameFormat("demo-pool-%d").build();
        
        //创建一个核心线程5 最大线程10 空闲线程等待1分钟的线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 1,
                TimeUnit.MINUTES, weekQueue, threadFactory);

    }
}

任务提交

  1. 如果正在运行的线程数小于核心线程数,就启动一个线程实行任务
  2. 如果核心线程数使用完,则将任务压入工作队列等待执行
  3. 如果工作队列已满,则创建新线程执行新的任务