一.了解线程前先了解进程
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础
通俗易懂的讲:打开一个应用程序就是在操作系统上开启了一个进程,进程之间可以相互独立运行,互不干扰,进程之间也可以相互访问和操作
二.什么是线程
是操作系统中能够进行运算调度的最小单位,线程包含在进程之中,一个进程可以并发多个线程,我们当前在写的代码,写的程序都是在主线程中进行的
简单理解线程:
就是代码从上到下运行的一条“管道”
三.多线程
我们目前写的代码,写的程序都是包含在主线程当中,可以通过代码开启新的线程,可以同时运行代码的多条“管道” 就叫多线程
四.语法
引用命名空间
using System.Threading;
1.声明一个新的线程 Thread 线程类
// 注意 线程执行的代码 需要封装到一个函数中 内部是一个委托 传入一个函数
// 新线程 将要执行的代码逻辑 被封装到了一个函数语句块中
Thread t = new Thread(NewThreadLogic);
//2.启动线程
t.Start();
声明了一个线程对象 括号内 构造方法需要传入一个函数(该构造方法内部是一个委托)
启动线程就是执行传入的函数
2.设置为后台线程
当前台线程都结束了的时候,整个程序也就结束了,即使还有后台线程正在运行,程序也会关闭
后台线程不会防止应用程序的进程被终止掉,如果不设置为后台线程 可能导致进程无法正常关闭
比如如果为设置一个线程为后台线程,这个线程中有死循环的话,那么收到这个线程的影响,整个进程都不会结束
当设置为后台线程时,如果主线程结束了,后台线程也会被强制结束
t.IsBackground = true;
3.关闭释放线程
如果开启的线程中不是死循环 是能够结束的逻辑 那么 不用刻意的去关闭它
如果是死循环 想要中止这个线程 有两种方式
(1)如果是死循环的线程,改变Bool变量的值即可关闭线程,Bool条件不满足,线程就不运行了
(2)语法关闭:(不适用于.Net Core)
Abort();
对象 = null
4.线程休眠
Thread.Sleep(1000);
毫秒为单位 1000ms = 1s;
五.线程之间共享数据
多个线程使用的内存是共享的,都属于该应用程序(进程)
所以要注意 当多线程 同时操作同一片内存区域时可能会出问题 会出现冲突
可以通过加锁的形式避免问题
示例:
while(true)
{
//当obj被锁住的时候 如果别的地方obj也被锁住的话
//就会先执行别的地方的代码逻辑 等锁住的地方的obj解锁了 也就是锁的地方代码执行完了
//才会执行下一个锁
lock(obj)
{
Console.SetCursorPosition(0, 0);
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("●");
}
}
六.多线程的意义
可以用多线程专门处理一些复杂耗时的逻辑
比如 寻路、网络通信等等
C#多线程总结:
多线程是多个可以同时执行代码逻辑的“管道”
可以通过代码开启多线程,用多线程处理一些复杂的可能影响主线程流畅度的逻辑
比如有个复杂的计算逻辑,如果在主线程中执行(因为一个线程中,代码是由上到下执行的),会导致主线程卡顿,影响用户体验
关键字 Thread
Unity中的多线程:
Unity是支持多线程的,只是新开线程无法访问Unity相关对象的内容 在多线程函数中不能访问任何Unity的组件相关对象,都会报错
因为在多线程中不能直接使用Unity的对象 所以我们可以通过创建一个容器 将计算好的结果放在这个容器中 让主线程来取用
这样通过容器 来间接的视线Unity中主线程和别的线程的之间的数据交互
注意:Unity中的多线程 要记住关闭
因为在Unity中写的多线程脚本挂载到场景中的游戏对象 游戏运行后结束运行 这个多线程还是在继续执行的,因为Unity本身是一个进程 相当于和Unity共生了