需求:有大量的数据处理,可以使用线程池,使处理速度加快
解决方案:使用线程池
为什么要用线程池
那先要明白什么是线程池
线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程。
使用线程池的好处
- 线程池改进了一个应用程序的响应时间。由于线程池中的线程已经准备好且等待被分配任务,应用程序可以直接拿来使用而不用新建一个线程。
- 线程池节省了CLR 为每个短生存周期任务创建一个完整的线程的开销并可以在任务完成后回收资源。
- 线程池根据当前在系统中运行的进程来优化线程时间片。
- 线程池允许我们开启多个任务而不用为每个线程设置属性。
- 线程池允许我们为正在执行的任务的程序参数传递一个包含状态信息的对象引用。
- 线程池可以用来解决处理一个特定请求最大线程数量限制问题。
线程池介绍
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
7个参数:
int corePoolSize:核心线程数目
int maximumPoolSize:最大线程数目
long keepAliveTime:临时线程存活的最大时间
TimeUnit unit:idle线程的空闲时间
BlockingQueue workQueue:阻塞队列,存放线程任务
ThreadFactory threadFactory:线程池创建线程时,调用该方法创建线程
RejectedExecutionHandler handler:拒绝策略
实现
创建工具类: MyThreadPool
package com.cennavi.audi_data_collect.utils;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
/**
* @author 70934
* @date 2019-12-15
* @desc 自定义线程池
*/
public class MyThreadPool {
private static ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("mythread-pool-%d").build();
private static final Integer CORE_SIZE = Runtime.getRuntime().availableProcessors() * 2;
/**
* 线程池
*/
public static ExecutorService pool = new ThreadPoolExecutor(CORE_SIZE, 200, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingDeque<>(4096 * 10), threadFactory, new ThreadPoolExecutor.AbortPolicy());
/**
* 执行一个任务
* @param task
*/
public static void execute(Runnable task) {
pool.execute(task);
}
public static Future<?> summit(Runnable task) {
return pool.submit(task);
}
public static boolean isTerminated() {
return pool.isTerminated();
}
public static void shutdown() {
pool.shutdown();
}
}
调用:将MyThreadPool.execute(() -> {});放在for循环中 启动线程池执行
MyThreadPool.execute(() -> {
System.out.println(
Thread.currentThread().getName() + "开始执行:" + df2.format(new Date()));
ReadCSV.readCSV(filePth, linkList, jjzdReadPath + "a=" + code0 + "/b=MQ/out.csv");
System.out.println(
Thread.currentThread().getName() + "执行结束:" + df2.format(new Date()));
});