多線程實現Thread.Start()與ThreadPool.QueueUserWorkItem兩種方式對比


Thread.Start(),ThreadPool.QueueUserWorkItem都是在實現多線程並行編程時常用的方法。兩種方式有何異同點,而又該如何取舍?

寫一個Demo,分別用兩種方式實現。觀察各自的現象。 

一個WorkMan class,其內的method doSomething()是每次異步線程調用的方法。該方法只是隨機的讓線程休眠一段時間。

public void doSomething()
{
     OnBegin(new EventArgs());

     // someone does something here
     var r = new Random();
     int sleepTime = r.Next(3000, 180000);
     Thread.Sleep(900000);

    OnCompleted(new EventArgs());
}

doSomething

Thread.Start()方式實現

workThreads = new Thread[NUMBER_OF_THREADS];

for (var i = 0; i < NUMBER_OF_THREADS; i++)
{
    arrWorkMen[i] = new WorkMan() { 
        WorkStarted = true,
        InstanceID = startThreadNumber
    };

    arrWorkMen[i].BeginHandler += HandleTaskBegin;
    arrWorkMen[i].CompletedHandler += HandleTaskCompleted;

    // create a thread and attach to the object
    var st = new ThreadStart(arrWorkMen[i].doSomething);
    workThreads[i] = new Thread(st);

    startThreadNumber++;
}

for (var i = 0; i < NUMBER_OF_THREADS; i++)
{
    Thread.Sleep(2000);
    workThreads[i].Start();
}                

Thread.Start()

ThreadPool.QueueUserWorkItem方式實現

for (var i = 0; i < NUMBER_OF_THREADS; i++)
{
    arrWorkMen[i] = new WorkMan()
    {
        WorkStarted = true,
        InstanceID = startThreadNumber
    };

    arrWorkMen[i].BeginHandler += HandleTaskBegin;
    arrWorkMen[i].CompletedHandler += HandleTaskCompleted;

    startThreadNumber++;
}

for (var i = 0; i < NUMBER_OF_THREADS; i++)
{
    Thread.Sleep(2000);
     ThreadPool.QueueUserWorkItem(o => arrWorkMen[i].doSomething());
}        

ThreadPool.QueueUserWorkItem

觀察兩種方式下,線程創建和回收的情況。

 

同樣的場景,每2秒鍾發起一新的線程,且每一線程均休眠2分鍾。Thread.Start()實現下,線程一路最高飆升到71個,然后隨着2分鍾后休眠線程的結束,線程個數始終在70、71之間徘徊。而ThreadPool.QueueUserWorkItem的實現下,線程個數到達最高73后,始終在72、73之間徘徊。

 

 

總體來說,做同樣的事情。ThreadPool方式產生的線程數略高於Thread.Start()。Thread.Start()產生的線程在完成任務后,很快被系統所回收。而ThreadPool(線程池)方式下,線程在完成工作后會被保留一段時間以備resue。所以,當需求需要大量線程並發工作的時候,不建議使用ThreadPool方式,因為它會保持很多額外的線程。

 

此處摘錄一段來自網絡的參考:

As for the ThreadPool, it is designed to use as few threads as possible while also keeping the CPU busy. Ideally, the number of busy threads is equal to the number of CPU cores. However, if the pool detects that its threads are currently not using the CPU (sleeping, or waiting for another thread), it starts up more threads (at a rate of 1/second, up to some maximum) to keep the CPU busy.

 Demo源碼:MultipleThreadsWayDemo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM