首先,配置一下线程池:
需要@EnableAsync开启异步
@Configuration
@EnableAsync
public class AppConfiguration{
@Bean(name = "taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数
executor.setCorePoolSize(4);
// 最大线程数
executor.setMaxPoolSize(8);
// 设置队列容量
executor.setQueueCapacity(16);
// 设置线程活跃时间(秒)
executor.setKeepAliveSeconds(60);
// 设置默认线程名称
executor.setThreadNamePrefix("pmc-");
// 设置拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
return executor;
}
}
以上步骤我们完成了线程池的配置,然后我们只需要在方法上使用注解就可以达到异步执行的效果。
@Async("taskExecutor")
public void updateProjTimePoint(ProjInfoDomain domain, Date timePointFSR) {
/**
* 该功能为配合BPM进行重大变更,重大变更目前是项目群阀门点时间变更和所有子项目同步进行变更
*
*/
LOGGER.info("======================[currentTread] = " + Thread.currentThread().getName() + "=============");
// 相关逻辑...
}
但是,今天在使用的时候遇到一个问题:当这个方法被当前类的另一个方法执行的时候,会导致只是执行单线程,需要在另外一个类调用这个类的这个异步方法的时候才会是多线程的。
- 当前方法被当前类的其他方法调用:
2018-07-18 15:34:27.972 - INFO 27608 [app - iec-wepm-service-8089] [rid - iec-wepm-service-8089-18071815412787671656465408] --- [ pmc-4] c.e.i.w.s.impl.ProjSetInfoServiceImpl : ======================[currentTread] = pmc-1=============
2018-07-18 15:34:27.973 - INFO 27608 [app - iec-wepm-service-8089] [rid - iec-wepm-service-8089-18071815412787671654384640] --- [ pmc-1] c.e.i.w.s.impl.ProjSetInfoServiceImpl : ======================[currentTread] = pmc-1=============
2018-07-18 15:34:27.975 - INFO 27608 [app - iec-wepm-service-8089] [rid - iec-wepm-service-8089-18071815412787671655089152] --- [ pmc-3] c.e.i.w.s.impl.ProjSetInfoServiceImpl : ======================[currentTread] = pmc-1=============
- 当前方法被其他类调用:
2018-07-18 15:44:27.972 - INFO 27608 [app - iec-wepm-service-8089] [rid - iec-wepm-service-8089-18071815412787671656465408] --- [ pmc-4] c.e.i.w.s.impl.ProjSetInfoServiceImpl : ======================[currentTread] = pmc-4=============
2018-07-18 15:44:27.973 - INFO 27608 [app - iec-wepm-service-8089] [rid - iec-wepm-service-8089-18071815412787671654384640] --- [ pmc-1] c.e.i.w.s.impl.ProjSetInfoServiceImpl : ======================[currentTread] = pmc-1=============
2018-07-18 15:44:27.975 - INFO 27608 [app - iec-wepm-service-8089] [rid - iec-wepm-service-8089-18071815412787671655089152] --- [ pmc-3] c.e.i.w.s.impl.ProjSetInfoServiceImpl : ======================[currentTread] = pmc-3=============
具体原因:
因为这个方法循环调用的,当在其他类中调用这个方法,每一次的循环都会创建这个对象,所以,每一次的创建和调用都是在一个独立的线程中进行的;如果是在当前对象中调用这个方法,那么在调用这个方法之前这个对象已经被创建了,所以结果就这样了。
当然,这个是一个很低级的错误,多线程的基础,但是有的时候就容易踩到这个坑。
微信公众号:CodeD