github代碼地址: https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service
html
假設一個需求用戶點擊某個頁面,咱們後臺須要向MQ推送信信息git
1,模擬的MQ服務,我這邊使用RabbitMQ (關於MQ 發送和監聽消息能夠參考個人博客:SpringBoot消息中間件RabbitMQ)github
//後臺監聽消息
@RabbitListener(queues = "brian.test") public void receiveMessage(User user){ logger.info("接收到MQ的消息體: " + user); }
2.向IOC容器中註冊一個ThreadPoolTaskExecutor實例spring
@Bean public ThreadPoolTaskExecutor brianThreadPool(){ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //核心線程數 executor.setCorePoolSize(8); //最大線程數 executor.setMaxPoolSize(16); //隊列中最大的數 executor.setQueueCapacity(8); //縣城名稱前綴 executor.setThreadNamePrefix("brianThreadPool_"); //rejectionPolicy:當pool已經達到max的時候,如何處理新任務 //callerRuns:不在新線程中執行任務,而是由調用者所在的線程來執行 //對拒絕task的處理策略 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //線程空閒後最大的存活時間 executor.setKeepAliveSeconds(60); //初始化加載 executor.initialize(); return executor; }
3.實現線程池併發推送消息多線程
/** * 多線程推送消息到MQ服務 */ public void sendMessageByThredPool(User user) throws ExecutionException, InterruptedException { Future<String> future = executor.submit(() -> { sendMessageService.sendMessage("brian","mymq",user);
logger.info("線程 [ " + Thread.currentThread().getName() + " ] 推送消息到MQ成功! " + new Date()); return Thread.currentThread().getName(); }); }
4. Controller層的調用併發
@PostMapping("/loop/sendMsg/userInfo") public ResponseEntity addUserInfo2MQ(@RequestBody User user) throws ExecutionException, InterruptedException { brianService.sendMessageByThredPool(user); return new ResponseEntity(user, HttpStatus.OK); }
5.利用postman 作壓力測試,測試接口app
5.1 postman作loop壓力測試,須要單建立一個Collections來測試,而且當前Collections值容許放一個測試用例,好比我下面的loopSendUserInfo異步
5.2 設置測試規則oop
點擊Preview ,能夠預覽測試數據post
6.查看測試結果
6.1 rabbitmq
6.2 log中能夠發現多個線程在推送消息
博客參考來源:1. 可取消的異步任務——FutureTask用法及解析
2. 多線程併發執行任務,取結果歸集。終極總結:Future、FutureTask、CompletionService、CompletableFuture