为何使用多线程
- 对于复杂的业务逻辑下,有时候需要使用多线程执行,以优化项目的执行速度
- 单线程同步执行的场景中,如果前边出现异常,会导致所有任务中断,异步执行没有这样的问题
多线程实现方式:线程池
减少线程创建和销毁的开销
线程池实现方式
- ThreadPoolExecutor
JDK 中的类,使用工具类方式进行
使用方式
- 单个线程池(快速使用)
//定义工具类
public class ThreadPoolUtil {
//线程池名称以及线程名称,以及定义执行器(可以定义多个线程池)
private static ThreadFactory testThreadPool = new ThreadFactoryBuilder()
.setNameFormat("test-Thread-pool-%d").build();
private static ExecutorService executor = new ThreadPoolExecutor(10, 100, 60L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(2000), testThreadPool, new ThreadPoolExecutor.AbortPolicy());
//直接执行方法,但是不能指定使用哪一个线程池
public static void executeTask(Runnable runnable) {
printThreadPoolState((ThreadPoolExecutor) executor, runnable);
executor.execute(runnable);
}
}
//使用线程池
ThreadPoolUtil.executeTask(
() ->
//执行方法
);
- 多个线程池(在工具类中增加以下方法)
//执行方法,同时可以指定使用哪一个线程池,通过下边的getExecutor获取指定线程池
public static void executeTask(Runnable runnable,ExecutorService executor) {
printThreadPoolState((ThreadPoolExecutor) executor, runnable);
executor.execute(runnable);
}
//
public static ExecutorService getExecutor(ThreadPoolType threadPoolType){
if (threadPoolType == ThreadPoolType.testThreadPool) {
return executor;
}
return null;
}
//使用线程池,使用testThreadPool线程池执行方法
ThreadPoolUtil.executeTask(() -> 执行方法, ThreadPoolUtil.getExecutor(ThreadPoolUtil.ThreadPoolType.testThreadPool));
- ThreadPoolTaskExecutor
Spring 中封装好的类,spring项目中使用更方便
使用方式:spring中对线程池进行了封装,可以用注解使用线程池
- spring使用配置文件进行线程池的配置
@Configuration
@EnableAsync
public class AsyncConfig {
//指定线程池名称
@Bean("testThreadPool")
public Executor testThreadPoolExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(100);
executor.setQueueCapacity(10);
//线程名称
executor.setThreadNamePrefix("testThreadPool-task");
//线程池满之后如何处理,此配置为抛出异常
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
executor.initialize();
return executor;
}
//可以增加上述方法增加线程池
}
//使用线程池,在要执行的方法上加此注解,括号内指定线程池
@Async("synchronizePool")
很显然,spring项目中ThreadPoolTaskExecutor更好用一点!