线程池与并行度
简介
对比创建500个线程和将500个线程放入线程池中。发现创建500个线程消耗了大量的操作系统资源,消耗的时间段;而把线程放到线程池中节省了内存和线程数,但是执行的时间变长了。
以下是代码实践:
using System;
using System.Diagnostics;
using System.Threading;
namespace 线程池与并行度
{
internal class Program
{
private static void Main()
{
const int numberOfOperation = 500;
//Stopwatch类,提供一组用于精确计时的方法和属性
var sw=new Stopwatch();
sw.Start();//开始计时
UseThreads(numberOfOperation);
sw.Stop();//结束计时
Console.WriteLine("Excution time using threads: {0}", sw.ElapsedMilliseconds);
sw.Reset();//停止计时并且将计时值清零
sw.Start();
UserThreadPool(numberOfOperation);
sw.Stop();
Console.WriteLine("Excution time using threads: {0}", sw.ElapsedMilliseconds);
Console.ReadKey();
}
private static void UseThreads(int numberOfOperation)
{
//CountdownEvent类在计数为零时得到信号
using (var countdown = new CountdownEvent(numberOfOperation))
{
Console.WriteLine("Scheduling work by creating threads");
for (var i = 0; i < numberOfOperation; i++)
{
var thread=new Thread(() =>
{
Console.Write("{0},",Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(TimeSpan.FromSeconds(0.1));
countdown.Signal();//向CountdownEvent注册信号,减少CurrentCount属性的值.
});
thread.Start();
}
countdown.Wait();//无限期阻塞当前线程,直到CurrentCount属性的值为零
Console.WriteLine();
}
}
private static void UserThreadPool(int numberOfOperation)
{
using (var countdown=new CountdownEvent(numberOfOperation))
{
Console.WriteLine("Starting work on a threadpool");
for (var i = 0; i < numberOfOperation; i++)
{
ThreadPool.QueueUserWorkItem(_ =>
{
Console.Write("{0},",Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(TimeSpan.FromSeconds(0.1));
countdown.Signal();
});
}
countdown.Wait();
Console.WriteLine();
}
}
}
}
总结
- CountdownEvent类可以用来同步线程CountdownEvent(int number)初始化,Signal()向CountdownEvent注册信号,减少CurrentCount属性的值,countdown.Wait()无限期阻塞当前线程,直到CurrentCount属性的值为零
- Stopwatch类,提供一组用于精确计时的方法和属性,Start()开始计时,Reset()停止计时并且将计时值清零,Stop()结束计时,ElapsedMilliseconds属性获取计时值,以毫秒计。
备注:学习《Multithreading in C# 5.0 Cookbook》Eugene Agafonov著的总结,以备日后查询。