乙個簡單的ThreadPool分析

2021-04-15 04:43:06 字數 2303 閱讀 2486

專案是多執行緒的,所以引入了執行緒池這個東西。池子是個老美寫的。在專案中表現的還不錯。所以把它摘出來,介紹給以後或許需要用到它的同行們。

關於為什麼要採用threadpool,原文已經提到了:建立乙個執行緒是需要開銷的;如果執行緒數量過大的話,cpu就會浪費很大的精力做執行緒切換。

threadpool的實現過程就是對workerthread的同步和通訊的管理過程。

我們來看**。

首先,在threadpool構造的時候,建立10個workerthread(size=10)並讓他們執行。每個workerthread執行緒都有個threadpool的引用,用於查詢threadpool的狀態和獲得同步鎖.workerthread執行以後,迴圈呼叫threadpool的方法進行查詢,如果沒有發現任務,threadpool告訴正在查詢的執行緒進入休眠狀態,workerthread釋放對查詢方法的鎖定.這樣在還沒有任務的時候,所有的10個workerthread都會進入休眠狀態,進入等待threadpool物件的等待鎖定池,只有threadpool物件發出notify方法(或notifyall)後workerthread執行緒才進入物件鎖定池準備獲得物件鎖進入執行狀態。

**片斷:

while ( !assignments.iterator().hasnext() )

wait();

接著,我們向threadpool中加入任務,這些任務都實現了runnable的run方法.(至於為什麼把任務都做成runnable,譯者至今也有些疑問?預定俗成?timertask也是實現自runnable,弄得初學者經常把真正執行的執行緒搞混).threadpool每assign乙個任務,就會發出一條訊息,通知它的等待鎖定池中的執行緒.各個執行緒以搶占的方式獲得物件鎖,然後很順利的獲得一條任務.並把此任務從threadpool裡面刪除.沒有搶到的繼續等待.

runnable r = (runnable)assignments.iterator().next();

assignments.remove(r);

workerthread從threadpool那裡獲得了任務,繼續向下執行。

target = owner.getassignment();

if (target!=null)

記住,這裡呼叫的是target.run();而不是呼叫的執行緒的start()方法。也就是說在這裡表現出的workerthread和task之間的關係僅僅是簡單的方法呼叫的關係,並沒有額外產生新執行緒。(這就是我上面納悶為什麼大家都實現runnable來做task的原因)

if (target!=null)

catch(throwable t)

owner.done.workerend();

} 在workerthread完成乙個task以後,繼續迴圈作同樣的流程.

在這個threadpool的實現裡面,jeff heaton用了乙個done類來觀察workerthread的執**況.和threadpoool的等待鎖定池不同,done的等待鎖定池裡面放的是初始化threadpool的執行緒(可能是你的主線程),我們叫他母線程.

在給出的測試例子中.母線程在呼叫complete()方法後進入休眠(在監視中等待),一開始是waitbegin()讓他休眠,在assign加入task以後,waitdone()方法讓他休眠.在workerthread完成乙個task以後,通知waitdone()起來重新檢查activethreads的數值.若不為0,繼續睡覺.若為0,那麼母線程走完,死亡(這個時候該做的task已經做完了).母線程走完,threadpool還存在嗎?答案是存在,因為workerthread還沒有消亡,他們在等待下一批任務,他們有threadpool的引用,保證threadpool依然存在.大家或許已經明白done這個類的作用了.

細心的讀者或許會發現,發生在done例項上的notify()並不是像threadpool上的notify()那樣每次都能完成一項工作.比如除了第乙個被assign的task,其他的task在assign進去的時候,發出的notify()對於waitdone()來說是句"狼來了".

最後在threadpool需要被清理得時候,使每乙個workerthread中斷(這個時候或許所有的workerthread都在休眠)並銷毀.記住這裡也是乙個非同步的過程.等到每乙個workerthread都已經銷毀,finalize()的方法體走完.threadpool被銷毀.

for (int i=0;i

threads[i].interrupt();

done.workerbegin();

threads[i].destroy(); }

done.waitdone();

為什麼有句done.workerbegin();?不明白.

嘗試實現乙個簡單的threadpool

參考資料 c 高併發多執行緒學習 一 c 併發程式設計 part 2 標頭檔案 include include include include include include include include include using namespace std class task task vi...

乙個執行緒池 ThreadPool 的使用

1 步驟一 include threadpool.h 2 步驟二 從irunobject派生自己的處理類 class cmyrunobject public irunobject bool autodelete void deleteinstance 派生類中必須實現的函式 run,initiali...

乙個簡單的verlig程式 乙個簡單C程式的介紹

我們前面學了c語言的一些理論知識,今天通過乙個簡單的程式先來看一看c語言程式是什麼樣子。然後再對程式中的 進行介紹。這個語句的功能是進行有關的預處理操作。include稱為檔案包含命令,後面尖括號的內容稱為標頭檔案或首檔案。此處指包含stdio.h系統標頭檔案,在下面主函式中使用的printf 函式...