一.配置线程池参数
@EnableAsync @Configuration public class TaskExecutorConfig { @Bean public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 设置核心线程数 executor.setCorePoolSize(60); // 设置最大线程数 executor.setMaxPoolSize(100); // 设置队列容量 executor.setQueueCapacity(300); // 设置线程活跃时间(秒) executor.setKeepAliveSeconds(60); // 设置默认线程名称 executor.setThreadNamePrefix("hiksion-"); // 设置拒绝策略 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 等待所有任务结束后再关闭线程池 executor.setWaitForTasksToCompleteOnShutdown(true); executor.initialize(); return executor; } }
二.调用方法上添加@Async注解
@Async @Transactional public void storePic(File file, byte[] bytes, ResourceRecordDto resouceRecordDto) throws IOException { // 将数据插入数据库(唯一键索引) ResourceRecordVo vo = null; try { vo = resourceRecordService.insertRecord(resouceRecordDto); } catch (DuplicateKeyException e) { log.error("数据文件已经存在,文件名称:{}", resouceRecordDto.getFileName()); throw e; } @Cleanup BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(file)); stream.write(bytes); // 数据处理打包好 ResourceRecordVo finalVo = vo; TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { @Override public void afterCommit() { if (finalVo != null) { ResourceRecordMessage msg = new ResourceRecordMessage(); msg.setResourceCompositeRecordId(finalVo.getResourceCompositeRecordId()); highDeviceSender.send(msg); } } }); }
三.注意同方法内调用失效问题
ApplicationContext.getBean(clazz)
由于注解的生效使用的是切面,所以同方法内调用时,要从容器中获取当前类,然后使用获取的当前类的对象调用同类中的有注解的方法才会生效..