生产环境中应该如何使用线程池

前言

多线程是Java开发当下无法回避的问题。今天就生产环境线程池的使用做简单记录。

Nacos中线程池的使用

nacos 配置中心 client 的源码部分, 有长连接的需求,源码路径 <src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java> .

ClientWorker():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
final ScheduledExecutorService executorService;
this.executorService = Executors
.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.Worker.longPolling." + agent.getName());
t.setDaemon(true);
return t;
}
});

this.executor.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
try {
checkConfigInfo();
} catch (Throwable e) {
LOGGER.error("[" + agent.getName() + "] [sub-check] rotate check error", e);
}
}
}, 1L, 10L, TimeUnit.MILLISECONDS);

checkConfigInfo():

1
2
executorService.execute(new LongPollingRunnable(i));
class LongPollingRunnable implements Runnable {}

但是我们知道阿里代码规范中是不推荐使用 Executors 创建线程池的。所以下边贴上我们在实际项目中的使用方式。

外呼

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
27
28
29
30
31
32
33
34
35
/**
* 创建线程池, 多线程处理推送话单数据
*/
private static final ExecutorService callExecutorService = initThreadPool("call-handler-");

/**
* 初始化线程池
*
* @return
*/
private static ExecutorService initThreadPool(String threadNamePrefix) {
// 定义线程名称
ThreadFactory namedThreadFactory = new ThreadFactory() {
private AtomicInteger id = new AtomicInteger();

@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setName(threadNamePrefix + id.getAndIncrement());
return thread;
}
};

int nThreads = Runtime.getRuntime().availableProcessors();

BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>();

// 超过队列策略:丢弃
RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.DiscardPolicy();

//Common Thread Pool
ExecutorService executorService = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, workQueue, namedThreadFactory, rejectedExecutionHandler);
return executorService;

}

spring中配置

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
27
28
@Configuration
public class TaskExecutorConfig {

// spring中集成
@Bean(name = "taskExecutor")
public TaskExecutor taskExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(Runtime.getRuntime().availableProcessors()); // 核心线程数
executor.setMaxPoolSize(Runtime.getRuntime().availableProcessors()); // 最大线程数
executor.setQueueCapacity(500); // 任务队列容量
executor.setThreadNamePrefix("upload-excel-");
executor.initialize();
return executor;
}


@Bean("uploadOssExecutor")
public ExecutorService uploadOssExecutor() {
return Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), r -> {
Thread t = new Thread(r);
t.setName("upload-oss");
t.setDaemon(true);
return t;
});
}


}

最后

本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】,您的支持是我写作的最大动力。