CS5L7-1——线程和线程池
CS5L7-1——线程和线程池
本章代码关键字
1 | ThreadPool //线程池类(静态类) |
回顾知识点——线程
关于Unity的多线程,具体看这里 ——> Unity是否支持多线程
- Unity支持多线程
- Unity中开启的多线程不能使用主线程中的对象
- Unity中开启多线程后一定记住关闭, (否则会与编辑器共生,直到关闭编辑器)
1 | Thread t; |
线程池
线程池相当于就是一个专门装线程的缓存池(Unity小框架套课中有对缓存池的详细讲解)
- 优点:节省开销,减少线程的创建,进而有效减少GC触发
- 缺点:不能控制线程池中线程的执行顺序,也不能获取线程池内线程取消/异常/完成的通知
命名空间:System.Threading
类名:ThreadPool
(线程池)
在多线程的应用程序开发中,频繁的创建删除线程会带来性能消耗,产生内存垃圾
为了避免这种开销 C# 推出了线程池 ThreadPool
类
ThreadPool
中有若干数量的线程,如果有任务需要处理时,会从线程池中获取一个空闲的线程来执行任务
任务执行完毕后线程不会销毁,而是被线程池回收以供后续任务使用
当线程池中所有的线程都在忙碌时,又有新任务要处理时,线程池才会新建一个线程来处理该任务,
如果线程数量达到设置的最大值,任务会排队,等待其他任务释放线程后再执行
线程池能减少线程的创建,节省开销,可以减少GC垃圾回收的触发
ThreadPool
是一个静态类,里面提供了很多静态成员,其中相对重要的方法有
-
获取可用的工作线程数和I/O线程数(应用程序内可开的最大线程数量)
1
2
3
4
5int workerThreadsNum;
int completionPortThreads;
ThreadPool.GetAvailableThreads(out workerThreadsNum, out completionPortThreads);
print(workerThreadsNum);
print(completionPortThreads); -
获取线程池中工作线程的最大数目和I/O线程的最大数目(该应用程序最多可用的线程池的线程数量)
1
2
3ThreadPool.GetMaxThreads(out workerThreadsNum, out completionPortThreads);
print(workerThreadsNum);
print(completionPortThreads); -
设置线程池中可以同时处于活动状态的工作线程的最大数目和I/O线程的最大数目
大于设置的次数的添加线程请求将保持排队状态,直到线程池线程变为可用,更改成功返回true,失败返回false1
2
3
4
5
6
7
8
9
10
11if (ThreadPool.SetMaxThreads(20, 20))
{
print("更改成功!");
ThreadPool.GetMaxThreads(out workerThreadsNum, out completionPortThreads);
print(workerThreadsNum);
print(completionPortThreads);
}
else
{
print("更改失败!");
} -
获取线程池中工作线程的最小数目和I/O线程的最小数目(该应用程序线程池内默认存在的线程数量)
1
2
3ThreadPool.GetMinThreads(out workerThreadsNum, out completionPortThreads);
print(workerThreadsNum);
print(completionPortThreads); -
设置 工作线程的最小数目和I/O线程的最小数目
更改成功返回true
,失败返回false
1
2
3
4
5
6
7
8
9
10
11if (ThreadPool.SetMinThreads(4, 4))
{
print("更改成功!");
ThreadPool.GetMinThreads(out workerThreadsNum, out completionPortThreads);
print(workerThreadsNum);
print(completionPortThreads);
}
else
{
print("更改失败!");
} -
将方法排入队列以便执行,当线程池中线程变得可用时执行
第一个参数就是多线程要执行的方法,方法需要一个object
类型参数
第二个参数就是第一个参数的函数的传入的参数1
2
3
4
5
6ThreadPool.QueueUserWorkItem((obj) =>
{
print(obj);
print("开启了一个线程");
}, "123456789");
print("主线程执行");要注意!我们不能控制线程执行的顺序!
1
2
3
4
5
6
7for (int i = 0; i < 10; i++)
{
ThreadPool.QueueUserWorkItem((obj) =>
{
print("第" + obj + "个任务");
}, i);
}