Springboot的并行多任务
一般生产环境不会直接这么用,但是springboot提供的这个功能还是很有用的,比如说我们自己做并发测试,模拟定时任务。
其他依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.0</version>
</dependency>
配置类
主要是为了初始化自定义的线程池,以及异步执行处理配置(单独的使用@Schedule是单线程的,配合@Async实现任务并行)
import cn.hutool.core.thread.ThreadFactoryBuilder;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.Random;
import java.util.concurrent.*;
/**
* @author ming
* @version 1.0.0
* @date 2020/8/21 18:23
**/
@Configuration
@EnableAsync
public class ScheduleConfig implements AsyncConfigurer {
/**
* 根据系统核心数来设置线程数: private static int corePoolSize = Runtime.getRuntime().availableProcessors();
* 核心线程数
*/
private static int corePoolSize = 100;
/**
* 最大线程数
*/
private static int maximumPoolSize = corePoolSize * 2;
/**
* 线程存活时间
*/
private static long keepAliveTime = 101L;
/**
* 阻塞队列大小
*/
private static final int CAPACITY = 1000;
/**
* 线程池命名
*/
private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNamePrefix("my-work-pool-").build();
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
keepAliveTime, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(CAPACITY),
namedThreadFactory,
(r, executor) -> userDefinedRejectionPolicy(r));
/**
* 拒绝策略;当任务太多来不及处理时,如何拒绝任务;
*
* @param r Runnable
*/
private static void userDefinedRejectionPolicy(Runnable r) {
//1、AbortPolicy策略:该策略会直接抛出异常,阻止系统正常工作;
//
//2、CallerRunsPolicy策略:如果线程池的线程数量达到上限,该策略会把任务队列中的任务放在调用者线程当中运行;
//
//3、DiscardOldestPolicy策略:该策略会丢弃任务队列中最老的一个任务,也就是当前任务队列中最先被添加进去的,马上要被执行的那个任务,并尝试再次提交;
//
//4、DiscardPolicy策略:该策略会默默丢弃无法处理的任务,不予任何处理。当然使用此策略,业务场景中需允许任务的丢失;
System.out.println(r.toString() + "执行了拒绝策略");
// TODO: 2020/8/19 这里写拒绝策略的相关逻辑 ,在某些场景下我们应该尽量避免丢弃任务
}
@Override
public Executor getAsyncExecutor() {
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
任务执行类
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* @author ming
* @version 1.0.0
* @date 2020/8/21 17:44
**/
@Component
@EnableScheduling
@EnableAsync
public class MyTask {
@Async
@Scheduled(cron = "0/5 * * * * ? ")
public void mySchedule() {
System.out.println("任务==1==");
try {
for (int i = 1; i <= 10; i++) {
System.out.println("<==1==>" + i);
Thread.sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Async
@Scheduled(cron = "0/5 * * * * ? ")
public void mySchedule2() {
System.out.println("任务==2==");
for (int i = 1; i <= 10; i++) {
System.out.println("<==2==>" + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}