一.配置線程池參數
@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)
由於注解的生效使用的是切面,所以同方法內調用時,要從容器中獲取當前類,然后使用獲取的當前類的對象調用同類中的有注解的方法才會生效..