8.线程和线程池

8.CSharp各版本新功能和语法-CSharp5功能和语法-线程和线程池


8.1 知识点

C#5的新增功能和语法有哪些

C#5的新增功能和语法主要有:

  1. 调用方信息特性(C#进阶套课——特性)
  2. 异步方法async和await

在学习异步方法async和await之前,我们必须补充一些知识点:

  1. 线程和线程池
  2. Task任务类

我们这节课先来回顾和学习线程和线程池

回顾线程

  1. Unity支持多线程
  2. Unity中开启的多线程不能使用主线程中的对象
  3. Unity中开启多线程后一定记住关闭
Thread t;

t = new Thread(() =>
{
    while (true)
    {
        print("123");
        Thread.Sleep(1000);
        //print(transform.position);//报错 不能使用主线程相关类
    }
});

t.Start();

//不停止线程的话开启的线程会和Unity编辑器进程共生死
private void OnDestroy()
{
    t.Abort();
}

线程池

命名空间:System.Threading

类名:ThreadPool(线程池)

在多线程的应用程序开发中,频繁的创建删除线程会带来性能消耗,产生内存垃圾。为了避免这种开销C#推出了线程池ThreadPool类。

ThreadPool中有若干数量的线程,如果有任务需要处理时,会从线程池中获取一个空闲的线程来执行任务。任务执行完毕后线程不会销毁,而是被线程池回收以供后续任务使用。当线程池中所有的线程都在忙碌时,又有新任务要处理时,线程池才会新建一个线程来处理该任务,如果线程数量达到设置的最大值,任务会排队,等待其他任务释放线程后再执行。线程池能减少线程的创建,节省开销,可以减少GC垃圾回收的触发。

线程池相当于就是一个专门装线程的缓存池)。

优点:节省开销,减少线程的创建,进而有效减少GC触发。

缺点:不能控制线程池中线程的执行顺序,也不能获取线程池内线程取消/异常/完成的通知。

ThreadPool是一个静态类,里面提供了很多静态成员。

ThreadPool.GetAvailableThreads方法 获取可用的工作线程数和I/O线程数

//ThreadPool类中的GetAvailableThreads方法 获取可用的工作线程数和I/O线程数
//不会受到SetMaxThreads设置后的影响
int num1;
int num2;
ThreadPool.GetAvailableThreads(out num1, out num2);
print(num1);//可用极限辅助线程的数目  1600
print(num2);//可用极限异步 I/O 线程的数目。 200

ThreadPool.SetMaxThreads方法 设置线程池中 可以同时处于活动状态的 工作线程的最大数目和I/O线程的最大数目

大于次数的请求将保持排队状态,直到线程池线程变为可用。更改成功返回true,失败返回false。

//ThreadPool类中的SetMaxThreads方法 设置线程池中 可以同时处于活动状态的 工作线程的最大数目和I/O线程的最大数目
//大于次数的请求将保持排队状态,直到线程池线程变为可用
//更改成功返回true,失败返回false
if (ThreadPool.SetMaxThreads(20, 20))
{
    print("更改工作线程的最大数目和I/O线程的最大数目成功");
}

ThreadPool.GetMaxThreads方法 获取线程池中工作线程的最大数目和I/O线程的最大数目

会受到SetMaxThreads设置后的影响。

//ThreadPool类中的GetMaxThreads方法 获取线程池中工作线程的最大数目和I/O线程的最大数目
//会受到SetMaxThreads设置后的影响
ThreadPool.GetMaxThreads(out num1, out num2);
print(num1);//20
print(num2);//20

ThreadPool.SetMinThreads方法 设置 工作线程的最小数目和I/O线程的最小数目

//ThreadPool类中的SetMinThreads方法 设置 工作线程的最小数目和I/O线程的最小数目
if (ThreadPool.SetMinThreads(5, 5))
{
    print("设置工作线程的最小数目和I/O线程的最小数目成功");
}

ThreadPool.GetMinThreads方法 获取线程池中工作线程的最小数目和I/O线程的最小数目

//ThreadPool类中的GetMinThreads方法 获取线程池中工作线程的最小数目和I/O线程的最小数目
ThreadPool.GetMinThreads(out num1, out num2);
print(num1);//5
print(num2);//5

ThreadPool.QueueUserWorkItem方法 将方法排入队列以便执行,当线程池中线程变得可用时执行

//ThreadPool类中的QueueUserWorkItem方法 将方法排入队列以便执行,当线程池中线程变得可用时执行

ThreadPool.QueueUserWorkItem((obj) =>
{
    print(obj);//NULL
    print("开启了一个线程");
});

//第一个参数可以设置obj对象
ThreadPool.QueueUserWorkItem((obj) =>
{
   print(obj);//123452435345
   print("开启了一个线程");
}, "123452435345");

//线程的执行顺序不可控 比如如下循环将线程入队 可能不会按顺序打印
for (int i = 0; i < 10; i++)
{
    ThreadPool.QueueUserWorkItem((obj) =>
    {
        print("第" + obj + "个任务");
    }, i);
}

总结

线程池 是一个C#写好的 装线程的缓存池

优点:可以在我们频繁的需要创建删除线程时提高性能,节约内存。

缺点:不能控制线程池中线程的执行顺序,也不能获取线程池内线程取消/异常/完成的通知


8.2 知识点代码

using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;

public class Lesson08_CSharp各版本新功能和语法_CSharp5功能和语法_线程和线程池 : MonoBehaviour
{

    #region 知识点二 回顾知识点——线程

    Thread t;

    //不停止线程的话开启的线程会和Unity编辑器进程共生死
    private void OnDestroy()
    {
        //t.Abort();
    }

    #endregion
    void Start()
    {
        #region 知识点一 C#5的新增功能和语法有哪些
        //1.调用方信息特性(C#进阶套课——特性)
        //2.异步方法async和await

        //在学习异步方法async和await之前
        //我们必须补充一些知识点
        //1.线程和线程池
        //2.Task任务类
        //我们这节课先来回顾和学习线程和线程池
        #endregion

        #region 知识点二 回顾知识点——线程

        //1.Unity支持多线程
        //2.Unity中开启的多线程不能使用主线程中的对象
        //3.Unity中开启多线程后一定记住关闭

        //t = new Thread(() =>
        //{
        //    while (true)
        //    {
        //        print("123");
        //        Thread.Sleep(1000);
        //        //print(transform.position);//报错 不能使用主线程相关类
        //    }
        //});

        //t.Start();


        #endregion

        #region 知识点三 补充知识点——线程池

        //命名空间:System.Threading
        //类名:ThreadPool(线程池)

        //在多线程的应用程序开发中,频繁的创建删除线程会带来性能消耗,产生内存垃圾
        //为了避免这种开销C#推出了 线程池ThreadPool类

        //ThreadPool中有若干数量的线程,如果有任务需要处理时,会从线程池中获取一个空闲的线程来执行任务
        //任务执行完毕后线程不会销毁,而是被线程池回收以供后续任务使用
        //当线程池中所有的线程都在忙碌时,又有新任务要处理时,线程池才会新建一个线程来处理该任务,
        //如果线程数量达到设置的最大值,任务会排队,等待其他任务释放线程后再执行
        //线程池能减少线程的创建,节省开销,可以减少GC垃圾回收的触发

        //线程池相当于就是一个专门装线程的缓存池(Unity小框架套课中有对缓存池的详细讲解)
        //优点:节省开销,减少线程的创建,进而有效减少GC触发
        //缺点:不能控制线程池中线程的执行顺序,也不能获取线程池内线程取消/异常/完成的通知

        //ThreadPool是一个静态类
        //里面提供了很多静态成员
        //其中相对重要的方法有


        //ThreadPool类中的GetAvailableThreads方法 获取可用的工作线程数和I/O线程数
        //不会受到SetMaxThreads设置后的影响
        int num1;
        int num2;
        ThreadPool.GetAvailableThreads(out num1, out num2);
        print(num1);//可用极限辅助线程的数目  1600
        print(num2);//可用极限异步 I/O 线程的数目。 200


        //ThreadPool类中的SetMaxThreads方法 设置线程池中 可以同时处于活动状态的 工作线程的最大数目和I/O线程的最大数目
        //大于次数的请求将保持排队状态,直到线程池线程变为可用
        //更改成功返回true,失败返回false
        if (ThreadPool.SetMaxThreads(20, 20))
        {
            print("更改工作线程的最大数目和I/O线程的最大数目成功");
        }


        //ThreadPool类中的GetMaxThreads方法 获取线程池中工作线程的最大数目和I/O线程的最大数目
        //会受到SetMaxThreads设置后的影响
        ThreadPool.GetMaxThreads(out num1, out num2);
        print(num1);
        print(num2);


        //ThreadPool类中的SetMinThreads方法 设置 工作线程的最小数目和I/O线程的最小数目
        if (ThreadPool.SetMinThreads(5, 5))
        {
            print("设置工作线程的最小数目和I/O线程的最小数目成功");
        }


        //ThreadPool类中的GetMinThreads方法 获取线程池中工作线程的最小数目和I/O线程的最小数目
        ThreadPool.GetMinThreads(out num1, out num2);
        print(num1);//5
        print(num2);//5


        //ThreadPool类中的QueueUserWorkItem方法 将方法排入队列以便执行,当线程池中线程变得可用时执行

        ThreadPool.QueueUserWorkItem((obj) =>
        {
            print(obj);//NULL
            print("开启了一个线程");
        });

        //ThreadPool.QueueUserWorkItem((obj) =>
        //{
        //    print(obj);
        //    print("开启了一个线程");
        //}, "123452435345");

        //线程的执行顺序不可控 比如如下循环将线程入队 可能不会按顺序打印
        for (int i = 0; i < 10; i++)
        {
            ThreadPool.QueueUserWorkItem((obj) =>
            {
                print("第" + obj + "个任务");
            }, i);
        }

        #endregion

        #region 总结
        //线程池 是一个C#写好的 装线程的缓存池

        //优点:可以在我们频繁的需要创建删除线程时提高性能,节约内存
        //缺点:不能控制线程池中线程的执行顺序,也不能获取线程池内线程取消/异常/完成的通知
        #endregion
    }


}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏