springboot下使用多線程


1 啟動類加上異步任務注解

@SpringBootApplication
@EnableScheduling
@EnableAsync//開啟異步任務
public class NpApplication{

    public static void main(String[] args) {
        SpringApplication.run( NpApplication.class, args);
    }

    @Bean(name="taskExecutor")
    public TaskExecutor workExecutor() {//線程池配置
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setThreadNamePrefix("Async-");
        threadPoolTaskExecutor.setCorePoolSize(5);
        threadPoolTaskExecutor.setMaxPoolSize(20);
        threadPoolTaskExecutor.setQueueCapacity(20000);
        threadPoolTaskExecutor.afterPropertiesSet();
        return threadPoolTaskExecutor;
    }


}

 

2 在需要的方法加上@Async注解(方法內的代碼為業務代碼,無須糾結)

@Async
    public Future<BmloanInfoQueryResponseRoot> sendLoanQuery(BmloanInfoQueryRequestBody requestBody) throws Exception {//需要響應結果,用future包裝
        BmloanInfoQueryRequestRoot root = new BmloanInfoQueryRequestRoot();
        root.setBody(requestBody);

        BmInitRequestHead.initRequestHeaderXml(root.getRequestHead(), bmChannelid, bmChanbankid, bmChanuserid, bmKhTranid);
        String sendXml = XMLUtil.convertToXml(root);
//        log.info("貸款申請信息批量查詢接口請求報文:{}", sendXml);
        ESBClient esbclient = new ESBClientImpl();
        esbclient.setTimeOut(600000);
        String res = esbclient.sendSync(sendXml, bmOpenandapplyUrl);
//        log.info("貸款申請信息批量查詢接口返回報文:{}", res);
        BmloanInfoQueryResponseRoot queryResponse = (BmloanInfoQueryResponseRoot) XMLUtil.convertXmlStrToObject(BmloanInfoQueryResponseRoot.class, res);
        return new AsyncResult<BmloanInfoQueryResponseRoot>(queryResponse);//包裝響應結果
    }

 

3 調用異步方法方法內的代碼為業務代碼,無須糾結

public void syncInfo() {
		List<String> businos = loanInfoDao.listNotSynch(100);
		if (businos.size() == 0) {
			return;
		}
		int size = businos.size();
		for (int i = 0; i < businos.size(); i++) {
			String busino = businos.get(i);
			BmloanInfoQueryRequestBody body = new BmloanInfoQueryRequestBody();
			body.setBusino(busino);
			try {
				Future<BmloanInfoQueryResponseRoot> queryResFuture = bmService.sendLoanQuery(body);//這里調用的異步方法
				futures.add(queryResFuture);//將異步結果加入list中,注意不能在這里直接獲取異步的結果,否則線程將阻塞,異步無效
				                           //futrues的定義===>>> List<Future<BmloanInfoQueryResponseRoot>> futures = new ArrayList<Future<BmloanInfoQueryResponseRoot>>();
				businoList.add(busino);
			} catch (Exception e) {
				log.error("貸款申請信息批量查詢異常=>流水號:{},錯誤信息:{}", busino, e.getMessage());
			}
		}
		dataHandle();
		syncInfo();//再調用
	}

  

4 注意事項

 4.1  第三步調用異步的方法 和 第二步的異步方法不能在同一個類中。

 4.2 異步方法得定義為public。

 4.3 在@Async標注的方法,並有@Transactional注解的;在其調用數據庫操作之時,將無法產生事務管理的控制,原因就在於其是基於異步處理的操作。

      可以將需要事務管理操作的方法放置到異步方法內部,在內部被調用的方法上添加@Transactional.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM