1、場景
最近做項目的時候遇到了一個小問題:從前台提交到服務端A,A調用服務端B處理超時,原因是前端一次請求往db插1萬數據,插完之后會去清理緩存、發送消息。
服務端的有三個操作 a、插DB b、清理cache c、發送消息。1萬條數據,說多不多,說少不少.況且不是單單insert。出現超時現象,不足為奇了吧~~
2、分析
如何避免超時呢?一次請求處理辣么多數據,可分多次請求處理,每次請求處理100條數據,可以有效解決超時問題. 為了不影響用戶的體驗,請求改為ajax 異步請求。
除此之外,仔細分析下場景. a 操作是本次處理的核心. 而b、c操作可以異步處理。換句話說,a操作處理完可以馬上返回給結果, 不必等b、c處理完再返回。b、c操作可以放在一個異步任務去處理。
3、實戰
(1)、ExecutorService : 任務提交
(2)、demo
異步任務類
public class ExecutorDemo { private ExecutorService executor = Executors.newFixedThreadPool(1); public void asynTask() throws InterruptedException { executor.submit(new Runnable() { @Override public void run() { try { Thread.sleep(10000);//方便觀察結果 } catch (InterruptedException e) { e.printStackTrace(); } int sum = 0; for(int i = 0; i < 1000; i++) { sum += i; } System.out.println(sum); } }); } }
客戶端模擬
public class Client { public static void main(String[] args) throws InterruptedException { boolean r = task2(); if(r) { task3(); } System.out.println("------------main end-----------"); } static boolean task2() throws InterruptedException { ExecutorDemo e = new ExecutorDemo(); e.asynTask(); System.out.println("------------task2 end-----------"); return true; } static void task3() throws InterruptedException { int j = 0; while(true) { if(j++ > 10000) { break; } } System.out.println("------------task3 end-----------"); } }
結果是醬紫的
------------task2 end----------- ------------task3 end----------- ------------main end----------- 499500
我們來分析下結果, task2是個異步任務,執行到task2,主線程不會在task2 阻塞,不用等待task2 處理完,可以往下執行task3.