還在使用Future輪詢獲取結果嗎?CompletionService快來了解下吧。
阿新 • • 發佈:2021-01-21
### 背景
二胖上次寫完引數校驗([《二胖寫引數校驗的坎坷之路》](https://mp.weixin.qq.com/s/IjKh5irDk1RSPtBLd7e9Vw))之後,領導一直不給他安排其他開發任務,就一直讓他看看程式碼熟悉業務。二胖每天上班除了偶爾跟坐在隔壁的前端小姐姐聊聊天,就是看看這些
枯燥無味的業務程式碼,無聊的一匹。雖然二胖已是久經職場的老油條了,但是看到同事們的週報都寫的滿滿的,而自己的週報,就一兩行,熟悉了什麼功能。心裡還是慌得一匹,畢竟公司不養閒人啊。於是乎二胖終於鼓起勇氣為了向領導表明自己的上進心,主動向領導要開發任務。領導一看這小夥子這麼有上進心,於是就到任務看板裡面挑了一個業務邏輯比較簡單的任務分配給了二胖。二胖拿到這個任務屁顛屁顛的回到座位。任務比較簡單,**就是通過爬蟲去爬取某些賣機票(某豬、某攜、某團等)的網站的一些機票,然後儲存到資料庫。**
### 同步入庫
二胖拿到任務,三下五除二就把任務完成了。
```java
public static void main(String[] args) throws InterruptedException {
String mouZhuFlightPrice = getMouZhuFlightPrice();
String mouXieFlightPrice = getMouXieFlightPrice();
String mouTuanFlightPrice = getMouTuanFlightPrice();
saveDb(mouZhuFlightPrice);
saveDb(mouXieFlightPrice);
saveDb(mouTuanFlightPrice);
}
/**
* 模擬請求某豬網站 爬取機票資訊
*
*
* @return
* @throws InterruptedException
*/
public static String getMouZhuFlightPrice() throws InterruptedException {
// 模擬請求某豬網站 爬取機票資訊
Thread.sleep(10000);
return "獲取到某豬網站的機票資訊了";
}
/**
* 模擬請求某攜網站 爬取機票資訊
*
* @return
* @throws InterruptedException
*/
public static String getMouXieFlightPrice() throws InterruptedException {
// 模擬請求某攜網站 爬取機票資訊
Thread.sleep(5000);
return "獲取到某攜網站的機票資訊了";
}
/**
* 模擬請求團網站 爬取機票資訊
*
* @return
* @throws InterruptedException
*/
public static String getMouTuanFlightPrice() throws InterruptedException {
// 模擬請求某團網站 爬取機票資訊
Thread.sleep(3000);
return "獲取到某團網站的機票資訊了";
}
/**
* 儲存DB
*
* @param flightPriceList
*/
public static void saveDb(String flightPriceList) {
// 解析字串 進行非同步入庫
}
```
這次二胖學乖了,任務完成了先去找下坐他對面的技術大拿(看他那髮際線就知道了)同事`“二狗”`讓二狗大拿幫忙指點一二,看看程式碼是否還能有優化的地方。畢竟領導對程式碼的效能、以及程式碼的優雅是有要求的。領導多次在部門的週會上提到讓我們多看看`“二狗”`寫的程式碼,學習下人家寫程式碼的**優雅、抽象、封裝**等等。二狗大概的瞄了下二胖寫的程式碼,提出了個小小的建議“**這個程式碼可以採用多執行緒來優化下哦,你看某豬這個網站耗時是拿到結果需要10s,其他的耗時都比它短,先有結果的我們可以先處理的,不需要等到大家都返回了再來處理的**”。
### 輪循futureList獲取結果
幸好二胖對多執行緒瞭解一點點,於是乎採用`future`的方式來實現。二胖使用一個`List`來儲存每個任務返回的`Future`,然後去輪詢這些`Future`,直到每個`Future`都已完成。由於需要先完成的任務需要先執行,且不希望出現因為排在前面的任務阻塞導致後面先完成的任務的結果沒有及時獲取的情況,所以在呼叫`get`方式時,需要將超時時間設定為`0`。
```java
public static void main(String[] args) {
int taskSize = 3;