多线程实现Thread.Start()与ThreadPool.QueueUserWorkItem两种方式对比

Thread.Start(),ThreadPool.QueueUserWorkItem都是在实现多线程并行编程时常用的方法。两种方式有何异同点,而又该如何取舍?

 

写一个Demo,分别用两种方式实现。观察各自的现象。

 

一个WorkMan class,其内的method doSomething()是每次异步线程调用的方法。该方法只是随机的让线程休眠一段时间。

 1 public void doSomething()
 2 {
 3      OnBegin(new EventArgs());
 4 
 5      // someone does something here
 6      var r = new Random();
 7      int sleepTime = r.Next(3000, 180000);
 8      Thread.Sleep(900000);
 9 
10     OnCompleted(new EventArgs());
11 }
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方式实现

 1 for (var i = 0; i < NUMBER_OF_THREADS; i++)
 2 {
 3     arrWorkMen[i] = new WorkMan()
 4     {
 5         WorkStarted = true,
 6         InstanceID = startThreadNumber
 7     };
 8 
 9     arrWorkMen[i].BeginHandler += HandleTaskBegin;
10     arrWorkMen[i].CompletedHandler += HandleTaskCompleted;
11 
12     startThreadNumber++;
13 }
14 
15 for (var i = 0; i < NUMBER_OF_THREADS; i++)
16 {
17     Thread.Sleep(2000);
18      ThreadPool.QueueUserWorkItem(o => arrWorkMen[i].doSomething());
19 }        
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

转载于:https://www.cnblogs.com/isun/p/4133127.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值