不管是使用哪种方式创建多线程,都出现一个有趣的现象,让我很是好奇。
while (!done)
{
<span style="background-color: rgb(255, 0, 0);"> Thread.Sleep(100);//关键部分</span>
++threadPoolCounters[n];
}
Console.WriteLine("&T" + n.ToString() + " = " + threadPoolCounters[n].ToString() + " ");
Interlocked.Increment(ref threadDone);
for (int i = 0; i < 10; i++)
{
ThreadPool.GetAvailableThreads(out workTheads, out IOTheads);
Console.WriteLine("AvailableThead:" + workTheads.ToString() + " ");
while(workTheads <= 0)//可用线程数>0
{
Thread.Sleep(500);
}
ThreadPool.QueueUserWorkItem(new WaitCallback(Count6Thread), i);
}
for (int i = 0; i < 10; i++)
{
Console.WriteLine("T" + i.ToString() + " = " + threadPoolCounters[i].ToString() + " ");
total += threadPoolCounters[i];
}
上面是我测试的主要代码段,注意红色部分,当我不用Sleep的时候,现象是:
发现了吗?只有前面4个线程执行了while循环里面的代码,后面都没有执行!但是当我加上上面的Sleep之后:
这个问题其实我之前就遇到过,但是没有去细想。
这是我原来的想法:出现这种现象的原因其实很简单,线程的并行数跟CPU有关,也就是说同一时刻,最多执行的线程数量是4(2*2核),只有当前线程执行完成或挂起或者时间片到了,才会调用下一线程,而我设置程序的运行时间很短,所以线程没有来得及切换。这些其实都是基础知识,也算一次温故吧!
但是当我今天看到大牛@老赵 的博客才发现,真正的原因是:CLR线程池限制了线程的创建速度不超过每秒2个。这样,即使在某个瞬时获得了大量的任务,CLR线程池也可以使用相对较少的线程来完成所有工作
怎么验证呢?SetMinThreads可以设置并行线程数,果然是可以得。或者我直接把程序计时器大小设大一点,效果也是可以得。
总结:是我瞎猜了,基础不牢啊,还需要学习!