原 薦 cache執行緒池對資料庫操作的飢餓問題

2021-07-24 20:01:53 字數 928 閱讀 6774

開源中國社群

2016-11-18 01:03

最近的工作中,因為程式需要大量進行資料庫查詢,我使用arrayblockingqueue模仿資料庫連線池,裡面初始化了固定數量的資料庫連線物件。

我的業務中,存在主任務生成子任務,然後通過future物件等待子任務返回結果的情況,為了避免已經在work佇列的主任務一直佔著cpu等待子任務返回,而子任務由於在task佇列中,因此得不到cpu資源,無法執行。我使用了cache執行緒池,讓所有任務都能被封裝為thread,可以得到cpu時間。

這個設計在測試環境的小資料集下執行是正常的,任務都能執行完,但提交到生產環境,就會在執行一段時候後出問題,現象是程式日誌停止,物件gc也停止,似乎程式停止或者在被阻塞住了。

後來通過jstack命令,將程式的執行緒呼叫棧幀拿來分析發現大量的執行緒是處於packing狀態,而且他們都是在arrayblockingqueue的take方法上阻塞,數量有436個。

接下來再看執行緒棧幀,發現執行緒cache執行緒池的執行緒id已經到了893,證明cache執行緒池中有大量執行緒生產,這些執行緒都處於packing狀態。只有乙個執行緒是runnable狀態,他獲得了dbhelper,正在查詢資料庫。

接下來修改**,主任務還是在cache執行緒池中,但其產生的子任務,放到另外乙個fix執行緒池中執行,這樣cpu就會將fix的worker佇列中的查詢先執行完,將dbhelper還回連線池,再去執行新的子任務,而不會建立過多的thread去等待dbhelper。修改完成後,重新執行程式,終於在日誌中發現了新的日誌,問題被解決。

其實到最後,我也不知道自己的分析是否完全正確。

Cache快取(資料庫鏈結池)

當同樣一段資料,很多人要訪問時,以前我總是不斷的從資料庫裡面讀出來到dataset中,然後慢慢的處理,但是每乙個使用者的訪問資料,都要進行同樣的步驟,感覺機子承受不了啊 找了幾種方法,顯示用cookies技術,發現不安全啊,於是使用session變數來盛放資料,伺服器變數,安全沒有話說的,接下來發現...

MFC的CRECORDSET對資料庫的操作

mfc資料庫操作系列 資料中間層 crecordset mfc資料庫介面分為兩種 odbc和ole db odbc而言提供開放的訪問方式,使用較為簡單,但是需要註冊資料庫,這導致在部署應用程式的時候需要重新布置資料庫,並且個人意見 資料庫操作不涉及大量的資料交換建議使用。crecordset為資料庫...

執行緒池 資料庫連線池

執行緒池的原理 來看一下執行緒池究竟是怎麼一回事?其實執行緒池的原理很簡單,類似於作業系統中的緩衝區的概念,它的流程如下 先啟動若干數量的執行緒,並讓這些執行緒都處於睡 眠狀態,當客戶端有乙個新請求時,就會喚醒執行緒池中的某乙個睡眠執行緒,讓它來處理客戶端的這個請求,當處理完這個請求後,執行緒又處於...