Skip to content

C# 多线程 03-使用线程池 03-线程池和并行度

🏷️ 《C# 多线程》

本节展示线程池如何工作于大量的异步操作,以及它与创建大量单独的线程的方式有何不同。

csharp
/// <summary>
/// 线程池和并行度
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
    const int numberOfOpeartions = 500;
    var sw = new Stopwatch();
    sw.Start();
    UseThreads(numberOfOpeartions);
    sw.Stop();
    Console.WriteLine($"使用线程的执行时间:{sw.ElapsedMilliseconds}ms");

    sw.Reset();
    sw.Start();
    UseThreadPool(numberOfOpeartions);
    sw.Stop();
    Console.WriteLine($"使用线程池的执行时间:{sw.ElapsedMilliseconds}ms");

    Console.ReadLine();
}

/// <summary>
/// 使用线程
/// </summary>
/// <param name="numberOfOperations"></param>
static void UseThreads(int numberOfOperations)
{
    using (var countdown = new CountdownEvent(numberOfOperations))
    {
        Console.WriteLine("通过创建线程执行处理");
        for (int i = 0; i < numberOfOperations; i++)
        {
            var thread = new Thread(() =>
            {
                Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}");
                Thread.Sleep(TimeSpan.FromSeconds(0.1));
                countdown.Signal();
            });
            thread.Start();
        }
        countdown.Wait();

        Console.WriteLine();
    }
}

/// <summary>
/// 使用线程池
/// </summary>
/// <param name="numberOfOperations"></param>
static void UseThreadPool(int numberOfOperations)
{
    using (var countdown = new CountdownEvent(numberOfOperations))
    {
        Console.WriteLine("在一个线程池中执行处理");
        for (int i = 0; i < numberOfOperations; i++)
        {
            ThreadPool.QueueUserWorkItem(_ => {
                Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}");
                Thread.Sleep(TimeSpan.FromSeconds(0.1));
                countdown.Signal();
            });
        }
        countdown.Wait();

        Console.WriteLine();
    }
}
通过创建线程执行处理
3
4
5

......

500
501
502

使用线程的执行时间:196ms
在一个线程池中执行处理
505
506
503

......

506
510
509

使用线程池的执行时间:8901ms

可以看出通过线程执行时,每一次循环都是创建一个新线程,总共创建了 500 个线程;而使用线程池则大约创建了 10 来个线程。

另外执行时间差距也很大,使用线程只用 200ms 左右,使用线程池则大约花费了 9s。

总的来说,使用线程耗时很短,但消耗了大量的系统资源;使用线程池,耗时比较长,但节约了大量的系统资源(内存和线程数)。