C#_ThreadPool

在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。如何利用已有对象来服务就是一个需要解决的关键问题,其实这就是一些”池化资源”技术产生的原因。比如大家所熟悉的数据库连接池正是遵循这一思想而产生的,线程池技术同样符合这一思想。

线程(Thread)

 线程:是Windows任务调度的最小单位。线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数,在一个应用程序中,常常需要使用多个线程来处理不同的事情,这样可以提高程序的运行效率,也不会使主界面出现无响应的情况。在这里主要介绍线程(Thread)、线程池(ThreadPool)两种不同创建线程的区别

  在通常的情况下,当我们需要开启一个新的线程时,我们直接通过Thread(继承自 System.Threading;)去创建一个新的线程,这样做有一个好处就是我们可以拿到这个新创建的线程,并且可以对这个线程去做一些相关的操作。但是通过创建一个新的线程会比较消耗资源,我们都知道,操作系统的资源是有限的,当用户访问的多了,需要开启的线程也跟着多了,当开启的线程超过系统的最大线程数时,系统就容易出现崩溃。下面我们来看一下创建100个线程所需要的时间

1
2
3
4
5
6
7
8
9
10
11
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 100; i++)
{
new Thread(() =>
{
UnityEngine.Debug.Log(1);
}).Start();
}
sw.Stop();
UnityEngine.Debug.Log("创建100个线程执行的时间为:" + sw.ElapsedMilliseconds.ToString());

运行后我们发现创建100个线程的时间为165ms,并且每个线程都不同。当创建的线程数超过系统的最大线程数的话,那么系统直接over了。有没有解决的办法呢,答案当然是有的,就是线程池(ThreadPool)技术。

线程池(ThreadPool)

 通过创建线程池对象,当需要使用线程时,就去池中看有没有创建好的线程,有的话就直接将创建好的线程拿出来,线程池中没有的话,就新创建一个线程,当线程使用完后,将放回线程池中供下次使用,这样不仅可以减少创建线程消耗的时间以及消耗的内存,还能够提高线程的利用率。

1
2
3
4
5
6
7
8
9
10
11
12
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 100; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback((s) =>
{
UnityEngine.Debug.Log("创建线程的ID为:"+Thread.CurrentThread.ManagedThreadId);
}));
}
sw.Stop();
UnityEngine.Debug.Log("创建100个线程执行的时间为:" + sw.ElapsedMilliseconds.ToString());

运行后我们发现创建100个线程的时间为35ms,从上面的运行结果我们可以发现,通过线程池去创建的线程,或者更准确点应该是去线程池获取线程比创建线程所花的时间地别很大,线程的ID也是重复的,这也是通过线程池来获取线程可以提高线程的利用率。

注意

是通过线程池获取的线程都默认为后台线程

坚持原创技术分享,您的支持将鼓励我继续创作!