利用多執行緒實現報表的高效匯出

2022-01-29 07:43:40 字數 2342 閱讀 2108

多執行緒、執行緒池、並發包每當談起這些詞彙,可能不是在面試就是在準備面試的路上了。

有句話叫「面試造航母,工作擰螺絲「,確實很多情況下我們是用不到這些東西的,但是學好這些東西對我們的日常工作也可能會產生意想不到的好處的。

臨近年末,收拾了下手頭工作,趁著最後兩天有些閒暇,準備著手優化下前段時間業務人員反饋的部分報表匯出速度過慢的問題。

報表的優化主要是涉及兩個方面,乙個是sql和資料庫層面的優化,另乙個就是**層面的優化了,本文主要講述**層面利用多執行緒處理的一點小總結。

在實際的使用過程中,一般我們都是用executors去建立執行緒池,如果有一些其他的需求,比如指定執行緒池的拒絕策略,阻塞佇列的型別,執行緒名稱的字首等等,我們可以採用自定義執行緒池的方式來解決。

public threadpoolexecutor(int corepoolsize,

int maximumpoolsize,

long keepalivetime,

timeunit unit,

blockingqueue

<

runnable

>

workqueue,

threadfactory threadfactory,

rejectedexecutionhandler handler) ;

其實這兩種方法的底層就是runnable,callable的實現。

多執行緒的一些基礎小知識,有興趣的同學可以園子裡翻翻其他同學的介紹,多執行緒、執行緒池、並發包這些東西無論是學習還是面試都是比較重要的。

仔細檢查了需要優化的報表,發現因為這個報表的實時性要求比較高,同時涉及大量資料的計算操作,在優化了sql後效率還是無法達到滿意的程度,所以決定採用多執行緒的方式多個執行緒同時處理不同的業務邏輯,最後在合併資料返回,以達到提高效率的目的。

初步決定採用executorservice的submit方法,將乙個複雜報表拆分為四個子執行緒執行並返回結果。同時採用並發包中的countdownlatch做同步器,等待 四個子執行緒執行完畢後,再在主線程進行資料合併操作。假如每個子執行緒的執行時長在10分鐘左右,如果採用原先的序列方式的話,四個業務處理大概需要40分鐘左右,現在這種並行的方式執行只需要十分鐘的處理時間。

long starttime =dateutils.getcurrentdatetime().gettime();

executorservice service = executors.newfixedthreadpool(4);

countdownlatch latch = new countdownlatch(4);

future

> borrowincrement = service.submit(new callable>()

});future

> beceiveaccount = service.submit(new callable>()

});future

> buaranteeaccount = service.submit(new callable>()

});future

> borrowerrepayment = service.submit(new callable>()

});latch.await();

list

borrowcapitalincrement =borrowincrement.get();

list

ownreceive =beceiveaccount.get();

list

ownaccountguan =buaranteeaccount.get();

list

borrower = borrowerrepayment.get();

上述**利用countdownlatch實現了執行緒同步,同時解決了原本序列執行時間較長的問題,在最終的效果上也是達到了預期的優化目標,比原報表的處理時長減少了四分之三的時間。

另外,有同學提出現在是實現了四個執行緒並行處理,處理時長大概在十分鐘左右。但是假如其中乙個執行緒出現了報錯,不在需要其他執行緒繼續執行,這個時候該怎麼處理呢?

確實是存在這個情況的,其實我們可以利用future物件的 cancel(boolean mayinterruptifrunning)來中斷其他執行緒,底層其實還是thread.interrupt()的方法實現。

總的來說技術方案上並沒有什麼特別的東西,但是有時候有沒有往這方面做就是乙個思考的問題了。其實在工作中九成以上的人每天都是在做crud的業務,但是即便是crud每個人做出來的東西還是有所不同的。多思考多實踐,其實多執行緒並沒有那麼遙不可及,即便是簡單的報表,也是可以做出不一樣的東西的。

最後,新年臨近,祝福大家新年快樂,也希望自己能夠在新的一年做乙個合格的creative worker。

PHP利用CURL MULTI實現多執行緒

php中的curl multi一類函式可以實現同時請求多個url,而不是乙個乙個依次請求,這就類似乙個程序實現了多個執行緒的功能,因此可以使用php利用curl multi實現完成多執行緒類的任務,下面就乙個利用php curl multi多執行緒採集網頁為例來說明一下。檢視 列印01 02 功能 ...

POI實現報表的匯出

檔案匯出方法 param resource list集合型別,要匯出的具體資料結合。param outputstream 輸出流,輸出的excel檔案儲存的具體位置。public void exportexcel listresource,outputstream outputstream 建立乙個...

PHP利用CURL MULTI實現多執行緒爆破

第二天我通過各種網路搜尋又搞出了乙個更快的方法,使用curl multi這個東西我在網路上也沒看懂到底是怎麼回事,但是網上的文章都千篇一律,全是copy的,我也就依葫蘆畫瓢,拼拼湊湊勉強能夠執行,先貼出 function fn function writelog str if post nums a...