NET多线程3 - 线程池

114 阅读1分钟

命名空间

System.Threading.ThreadPool

为什么使用线程池

线程的创建和销毁是比较昂贵的操作。

对象池的思想

事先创建好几个对象,需要就从池中分配,用完就返回池中。

注意要点

  1. 线程池,只适合短时操作,不要阻塞线程池线程。
  2. 线程池的线程是后台线程。
  3. 线程池的线程数量有上限。
  4. ASP.NET 使用自己的线程池。

线程另一种分类(线程池)

工作线程(worker thread)

主要处理占用CPU进行算法计算等

IO线程(I/O thread)

主要处理网络请求,硬盘文件读写等

优缺点

内存

电脑的内存是有限的,不用线程池,每个线程都会占用内存,如果并发数量很多,内存会爆掉。

并发性

使用线程池,当并发超过一定数量,则会排队,所以,并行的请求处理时间会被延长。

使用线程池

使用 QueueUserWorkItem(worker thread)

Thread thread = new Thread(() => 
{
    // 打印 False
    Console.WriteLine(Thread.CurrentThread.IsThreadPoolThread);
});
thread.Start();
thread.Join();
ThreadPool.QueueUserWorkItem((obj) =>
{
    // 打印 True
    Console.WriteLine(Thread.CurrentThread.IsThreadPoolThread);
});
Console.ReadLine();

委托异步调用使用了线程池(worker thread)

public delegate void HiDelegate();
static void Main(string[] args)
{
    HiDelegate sayHi = new HiDelegate(SayHi);
    IAsyncResult ar = sayHi.BeginInvoke((x) => { }, sayHi);
    sayHi.EndInvoke(ar);
    Console.ReadLine();
}
static void SayHi()
{
    // True 使用线程池
    Console.WriteLine(Thread.CurrentThread.IsThreadPoolThread);
}

System.Threading.Timer 使用了线程池(worker thread)

System.Threading.Timer timer;
timer = new Timer((obj) =>
{
    // True 使用线程池
    Console.WriteLine(Thread.CurrentThread.IsThreadPoolThread);
});
timer.Change(500, 500);
Console.ReadLine();

System.ComponentModel.BackgroundWorker使用了线程池(worker thread)

System.ComponentModel.BackgroundWorker bgWorker;
bgWorker = new BackgroundWorker();
bgWorker.DoWork += (sender, e) =>
{
    // True 使用线程池
    Console.WriteLine(Thread.CurrentThread.IsThreadPoolThread);
};
bgWorker.RunWorkerAsync();
Console.ReadLine();

标准的取消线程任务

使用System.Threading.CancellationTokenSource

using (CancellationTokenSource cts = new CancellationTokenSource())
{
    CancellationToken token = cts.Token;
    ThreadPool.QueueUserWorkItem((obj) =>
    {
        while (!token.IsCancellationRequested)
        {
            Console.WriteLine("hi");
        }
    });
    Thread.Sleep(3);
    cts.Cancel(); // 取消线程执行
}
Console.ReadLine();

完。