线程池配置
@Configuration
public class AsyncConfiguration {
private int corePoolSize = 10;
private int maxPoolSize = 100;
private int queueCapacity = 100;
private int KeepAliveSeconds = 200;
private String namePrefix = "async-";
@Bean(name = "asyncPoolTaskExecutor")
public ThreadPoolTaskExecutor executor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程数
executor.setCorePoolSize(corePoolSize);
//线程池维护线程的最大数量,只有在缓冲队列满了之后才会申请超过核心线程数的线程
executor.setMaxPoolSize(maxPoolSize);
//缓存队列
executor.setQueueCapacity(queueCapacity);
//设置线程的空闲时间,当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
executor.setKeepAliveSeconds(KeepAliveSeconds);
//异步方法内部线程名称
executor.setThreadNamePrefix(namePrefix);
/**
* 当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略
* 通常有以下四种策略:
* ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
* ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
* ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
* ThreadPoolExecutor.CallerRunsPolicy:重试添加当前的任务,自动重复调用 execute() 方法,直到成功
*/
//ThreadPoolExecutor.CallerRunsPolicy:重试添加当前的任务,自动重复调用 execute() 方法,直到成功
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}
Service
public interface DemoService {
/**
* 方法
* @throws InterruptedException
*/
void d(int a) throws InterruptedException;
}
ServiceImpl
@Service("demoService") //设置好bean
public class DemoServiceImpl implements DemoService {
@Override
public void d(int a) throws InterruptedException {
for (int i = 0; i < 5; i++) {
Thread.sleep(100);
System.out.println("异步线程"+a+":" +i);
}
}
}
继承 Runnable
public class DemoRunnable implements Runnable {
DemoService demoService = SpringUtil.getBean("demoService");
private final Integer a;
private final CountDownLatch countDownLatch;
public DemoRunnable(Integer a, CountDownLatch countDownLatch) {
this.a = a;
this.countDownLatch =countDownLatch;
}
@SneakyThrows
@Override
public void run() {
demoService.d(a);
// 执行完任务之后,执行任务线程数-1
countDownLatch.countDown();
}
}
这边是通过定时器启动的
@Component
public class DemoTask {
@Resource(name = "asyncPoolTaskExecutor")
public ThreadPoolTaskExecutor executor;
@Scheduled(cron = "00 33 16 * * ?")
public Object demo() throws InterruptedException {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
//构建计数
CountDownLatch countDownLatch = new CountDownLatch(list.size());
for (Integer integer : list) {
executor.execute(new DemoRunnable(integer,countDownLatch));
}
// 阻塞等待线程池任务执行完
countDownLatch.await();
return "ok";
}
}
执行结果
从结果上能够看出,线程1到5是异步一起在跑的,循环五次
异步线程2:0
异步线程1:0
异步线程3:0
异步线程4:0
异步线程5:0
异步线程1:1
异步线程3:1
异步线程2:1
异步线程4:1
异步线程5:1
异步线程3:2
异步线程1:2
异步线程2:2
异步线程4:2
异步线程5:2
异步线程1:3
异步线程3:3
异步线程2:3
异步线程4:3
异步线程5:3
异步线程3:4
异步线程1:4
异步线程2:4
异步线程4:4
异步线程5:4