1. 程式人生 > >關於Java中單執行緒處理資料過慢的問題解決

關於Java中單執行緒處理資料過慢的問題解決

有個需求呼叫了外部介面查詢客戶的違章資訊,一共一千多輛車,檢視日誌的時候這段程式居然跑了有半個多小時。

之前的處理邏輯是將所有的資料遍歷,根據客戶的車輛資訊一個個去呼叫介面。

這麼長時間,肯定要優化。想了想:可以將查出來的所有資料分片,分n片,啟動n個執行緒,分別去執行查介面的功能。由於公司使用的伺服器一般四核cpu,所以使用可以將資料分成8片,並啟動8個執行緒。(一個併發程式開多少執行緒合適?

 

一、首先是啟動8個執行緒,這裡使用了JUC的執行緒池。

有一篇專門介紹建立執行緒池的方法:《Java ExecutorService四種執行緒池的例子與說明》

二、然後將資料分片

之前也專門寫過一個文章,可以出門左拐,這裡就不詳細介紹了。 ==》List分片處理

三、處理資料

 

由於是單機程式,是將所有的資料查出來,然後分片處理,所以不會出現各種併發型別問題。但是還是有一個小小的問題,之前計算這段程式的處理時間失效了。原因是之前用主執行緒記錄時間,程式也跑在主執行緒上,所以只需要在程式的前後new 兩個時間,計算差值就可以了。現在使用子執行緒處理資料後,這樣處理就不可以了。

之前處理執行時間的邏輯:

@RequestMapping("send-break-rules-msg")
    public void sendMsgToClient() {
        Date startDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.info("<<<<<<<<<<<<<<<send break rules msg start at:{}>>>>>>>>>>>>>>", sdf.format(startDate));

        // 從資料庫查資料

        // ......

        // 查詢外部介面,處理資料       

        Date endDate = new Date();
        log.info("<<<<<<<<<<<<<<<send break rules msg end at:{}>>>>>>>>>>>>>>", sdf.format(endDate));
        log.info("<<<<<<<<<<<<<<<send break rules msg cost:{}>>>>>>>>>>>>>>", endDate.getTime() - startDate.getTime());
    }

在主執行緒中使用CountDownLatch工具類,在每個子執行緒的處理邏輯最後加上 countDownLatch.countDown();

經過這樣的處理之後,這段程式完美的別控制在了5分鐘以內。