一、什么是多线程
1、进程
当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。 而一个进程又是由多个线程所组成的。
2、线程
线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。
3、句柄
句柄是Windows系统中对象或实例的标识,这些对象包括模块、应用程序实例、窗口、控制、位图、GDI对象、资源、文件等。
4、多线程
(1)多线程概念
多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。
(2)多线程优点
可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。(牺牲空间计算资源,来换取时间)
(3)多线程缺点
- 线程也是程序,所以线程运行需要占用计算机资源,线程越多占用资源也越多。(占内存多)
- 多线程需要协调和管理,所以需要CPU跟踪线程,消耗CPU资源。(占cpu多)
- 线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题。多线程存在资源共享问题)
- 线程太多会导致控制太复杂,最终可能造成很多Bug。(管理麻烦,容易产生bug)
(4)为什么计算机可以多线程
- 程序运行需要计算机资源,操作系统就会去申请CPU来处理,CPU在执行动作的时候是分片执行的。
- 分片:把CPU的处理能力进行切分,操作系统在调度的时候,按照切片去处理不同的计算需求,按照规则分配切片计算资源,对于同一个计算机核心来讲,所有的运行都是串行的,但是因为分片的存在,感觉几个程序同时在向前推进。
(5)何时建议使用多线程
- 当主线程试图执行冗长的操作,但系统会卡界面,体验非常不好,这时候可以开辟一个新线程,来处理这项冗长的工作。
- 当请求别的数据库服务器、业务服务器等,可以开辟一个新线程,让主线程继续干别的事。
- 利用多线程拆分复杂运算,提高计算速度。
(6)何时不建议使用多线程
当单线程能很好解决,就不要为了使用多线程而用多线程。
5、同步,异步
(1)同步方法
线性执行,从上往下依次执行,同步方法执行慢,消耗的计算机资源少。
(2)异步方法
线程和线程之间,不再线型执行,多个线程总的耗时少,执行快,消耗的计算机资源多,各线程执行是无序的。
6、C#中的多线程
Thread/ThreadPool/Task 都是C#语言在操作计算机的资源时封装的帮助类库。
private static void NewThreadLogic() {
// 新开线程 执行的代码逻辑 在该函数语句块中
while (isRuning)
// Thread.Sleep(1000);
// Console.WriteLine("新开线程代码逻辑");
{
lock (obj) {
Console.SetCursorPosition(10, 5);
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("■");
}
}
}
// 线程类 Thread
// 需要引用命名空间 using System.Threading;
// 1.申明一个新的线程
// 注意 线程执行的代码 需要封装到一个函数中
// 新线程 将要执行的代码逻辑 被封装到了一个函数语句块中
Thread t = new Thread(NewThreadLogic);
// 2.启动线程
t.Start();
// 3.设置为后台线程
// 当前台线程都结束了的时候,整个程序也就结束了,即使还有后台线程正在运行
// 后台线程不会防止应用程序的进程被终止掉
// 如果不设置为后台线程 可能导致进程无法正常关闭
t.IsBackground = true;
// 4.关闭释放一个线程
// 如果开启的线程中不是死循环 是能够结束的逻辑 那么 不用刻意的去关闭它
// 如果是死循环 想要中止这个线程 有两种方式
// 4.1-死循环中bool标识
// Console.ReadKey();
// isRuning = false;
// Console.ReadKey();
// 4.2-通过线程提供的方法(注意在.Net core版本中无法中止 会报错)
// 中止线程
// try
// {
// t.Abort();
// t = null;
// }
// catch
// {
// }
// 5.线程休眠
// 让线程休眠多少毫秒 1s = 1000毫秒
// 在哪个线程里执行 就休眠哪个线程
// Thread.Sleep(1000);
// 线程之间共享数据
// 多个线程使用的内存是共享的,都属于该应用程序(进程)
// 所以要注意 当多线程 同时操作同一片内存区域时可能会出问题
// 可以通过加锁的形式避免问题
// lock
// 当我们在多个线程当中想要访问同样的东西 进行逻辑处理时
// 为了避免不必要的逻辑顺序执行的差错
// lock(引用类型对象)
while (true) {
lock (obj) {
Console.SetCursorPosition(0, 0);
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("●");
}
}
// 多线程对于我们的意义
//可以用多线程专门处理一些复杂耗时的逻辑
//比如 寻路、网络通信等等
多线程是多个可以同时执行代码逻辑的“管道”
可以通过代码开启多线程,用多线程处理一些复杂的可能影响主线程流畅度的逻辑
关键字 Thread