Java 线程池

default

线程池定义

线程池是一个放置线程的容器,其中保留部分存活的线程,以备随时使用,避免了每次使用时都需要创建及销毁线程的耗时操作,同时可以方便统一控制线程的数量,配置线程参数、任务队列、拒绝策略。

推荐的线程池的创建方法

Java 自带的 ThreadPoolExecutor

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public ThreadPoolExecutor(
    // 核心线程数量
    int corePoolSize,
    // 最大线程数量
    int maximumPoolSize,
    // 存活时间
    long keepAliveTime,
    // 时间单位
    TimeUnit unit,
    // 任务队列
    BlockingQueue<Runnable> workQueue,
	// 线程创建工厂
    ThreadFactory threadFactory,
    // 拒绝策略
    RejectedExecutionHandler handler
)
参数名 解释
corePoolSize 核心线程数量,保证存活随时可用的线程数量。CPU 密集型操作,则设置为 CPU核数 + 1;IO 密集型则设置为 CPU核数 * 2
maximumPoolSize 最大线程数量,一般与核心线程数量一致。可基于最大 CPU 利用率、内存利用率、IO 利用率进行限制。
keepAliveTime 线程空闲时间,一般为 60 s
unit 一般设置为秒 TimeUnit.SECOND
workQueue 等待执行的任务队列。包括无界队列(LinkedBlockingQueue)、有界队列(ArrayBlockingQueue:一般有界队列;PriorityBlockingQueue:优先级阻塞队列)、同步移交队列(没有可用线程时异常)。
threadFactory 线程工厂。可配置线程名称、线程组、优先级、守护进程状态等
handler 队列已满时的拒绝策略。默认实现包括四种:AbortPolicy(丢弃任务,抛出异常)、CallRunsPolicy(由当前调用的任务线程执行)、DiscardPolicy(忽视该任务)、DiscardOldestPolicy(剔除最老的任务)

SpringBoot 中封装的 ThreadPoolTaskExecutor

封装 ThreadPoolExecutor,提供了默认配置参数,简化了线程池的创建。但是仍然建议手动创建,根据实际情况配置其参数。

其他线程池

一般情况下不推荐使用以下线程池, 酌情使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 该线程池中只有一个线程
Executors.newSingleThreadExecutor();

// 该线程池不限制线程数量
Executors.newCachedThreadPool();

// 该线程池固定线程数,任务队列采用的无界队列(LinkedBlockingQueue)
Executors.newFixedThreadPool(100);

// 该线程池固定线程数,可执行延迟任务,也可执行带返回值的任务
Executors.newScheduledThreadPool(100);

线程池的任务队列

LinkedBlockingQueue

ArrayBlockingQueue

PriorityBlockingQueue

需要自己实现 Runnable,否则,默认 Comparator 是 null,使用元素的 compareTo 方法进行比较。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 实现 Runnable
class MyTask implements Runnable {

    private int priority;

    public int getPriority() {
        return priority;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

public static void main(String[] args) throws InterruptedException {
    // 创建比较器
    Comparator<MyTask> comparator = Comparator.comparingInt(MyTask::getPriority);

    // 新建线程池
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10,10,1000,TimeUnit.MICROSECONDS,new PriorityBlockingQueue(100, comparator));
}
Licensed under CC BY-NC-SA 4.0
Gear(夕照)的博客。记录开发、生活,以及一些不足为道的思考……