计算机概念
进
计算机概念
进程
程序在服务器运行时,占据的计算资源合计,称之为进程。进程之间不会相互干扰,但是进程间的通信比较困难(分布式)。
线程
程序执行的最小单位,相应操作的最小执行流,线程也包含自己的计算资源。线程是属于进程的,一个进程可以有多个线程。
多线程
一个进程里面,有多个线程并发执行
C#
多线程Thread
`Thread`是一个类,就是一个封装,是.NET对线程对象的抽象封装,通过`Thread`去完成的操作,最终是通过像操作系统请求得到的执行流
*   `CurrentThread`:当前线程–任何操作执行都是线程完成的,即获得运行当前这句话的线程
*   `ManagerThreadId`:是.NET平台给Thread起的名字,就是一个`int`值,尽量不重复
*   同步单线程方法:按顺序执行,每次调用完成后才能进下一行,是同一个线程运行的
*   异步多线程方法:发起调用,不等待结果就直接进入下一行(主线程),动作会由一个新线程来执行(子线程)
特点
界面卡顿
*   同步单线程方法卡界面 —- 主(UI)线程线程忙于计算,所以不能相应
*   异步多线程不卡界面 —- 计算任务交给子线程,主(UI)线程已经闲置,可以相应别的操作
*   多线程对于C/S:点击按钮后能不卡死,例如:上传文件界面不卡死
*   多线程对于B/S:例如:用户注册时同时发邮件/发短信/写日志
执行速度
*   同步单线程方法慢 —- 因为只有一个线程在计算
*   异步多线程方法快 —- 因为多个线程并发计算
*   多线程就是用资源换性能
*   但是两者的速度差不是线性增长,例如1个线程耗时1000毫秒,5个线程不代表能做到耗时200毫秒。说明多线程的协调管理由额外的成本,同时资源也是由上限的
*   所以:线程并不是越多越好
无序性
*   启动无序:几乎同一时间向操作系统请求线程,因为线程时操作系统资源,CLR只能去申请,具体时什么顺序启动这个无法掌握
*   执行时间不确定:同个线程同个任务耗时都不一样,更何况多个任务多个线程。这跟操作系统的资源调度策略有关
*   结束无序:上面的都无序,结束时间怎么可能有序
注意
使用多线程时,千万不要通过延时等方式去掌控顺序
多线程控制顺序
异步回调
死循环IsCompleted等待
信号量
EndInvoke获得返回值
使用各个版本的多线程处理方式
Thread
示例:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | 
 ThreadStart threadHandler = () =>
 {
 Console.WriteLine($"Thread Start。。。{Thread.CurrentThread.ManagedThreadId}");
 Thread.Sleep(2000);
 Console.WriteLine($"Thread End。。。{Thread.CurrentThread.ManagedThreadId}");
 };
 var thread = new Thread(threadHandler);
 thread.Start();
 
 | 
ThreadPool
示例:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | 
 
 
 WaitCallback callback = o =>
 {
 Console.WriteLine($"ThreadPool Start。。。{Thread.CurrentThread.ManagedThreadId}");
 Thread.Sleep(2000);
 Console.WriteLine($"ThreadPool End。。。{Thread.CurrentThread.ManagedThreadId}");
 };
 ThreadPool.QueueUserWorkItem(callback);
 
 | 
Task
示例:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | 
 Action action = () =>
 {
 Console.WriteLine($"Task Start。。。{Thread.CurrentThread.ManagedThreadId}");
 Thread.Sleep(2000);
 Console.WriteLine($"Task End。。。{Thread.CurrentThread.ManagedThreadId}");
 };
 Task task = new Task(action);
 task.Start();
 
 | 
Parallel
示例:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | 
 
 Parallel.Invoke(() =>
 {
 Console.WriteLine($"Parallel 1 Start。。。{Thread.CurrentThread.ManagedThreadId}");
 Thread.Sleep(2000);
 Console.WriteLine($"Parallel 1 End。。。{Thread.CurrentThread.ManagedThreadId}");
 },
 () =>
 {
 Console.WriteLine($"Parallel 2 Start。。。{Thread.CurrentThread.ManagedThreadId}");
 Thread.Sleep(2000);
 Console.WriteLine($"Parallel 2 End。。。{Thread.CurrentThread.ManagedThreadId}");
 },
 () =>
 {
 Console.WriteLine($"Parallel 3 Start。。。{Thread.CurrentThread.ManagedThreadId}");
 Thread.Sleep(2000);
 Console.WriteLine($"Parallel 3 End。。。{Thread.CurrentThread.ManagedThreadId}");
 });
 
 | 
Task比较全面示例
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 
 | public void Coding(string dev, string module)  {
 var random = new Random();
 var stopWatch = new Stopwatch();
 stopWatch.Start();
 Console.WriteLine($"{dev}开发{module}模块 开始.......... ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
 Thread.Sleep(random.Next(1000, 5000));
 stopWatch.Stop();
 Console.WriteLine($"{dev}开发{module}模块 完成.......... ManagedThreadId={Thread.CurrentThread.ManagedThreadId}   共耗时{stopWatch.ElapsedMilliseconds}毫秒");
 }
 
 public void AllJob()
 {
 Console.WriteLine("谈需求...");
 Console.WriteLine("选成员...");
 Console.WriteLine("分配模块...");
 
 List<Task> tasks = new List<Task>();
 
 tasks.Add(Task.Run(() => Coding("张小三", "用户管理")));
 tasks.Add(Task.Run(() => Coding("李筱思", "商品管理")));
 tasks.Add(Task.Run(() => Coding("王小五", "订单管理")));
 tasks.Add(Task.Run(() => Coding("赵小六", "售后管理")));
 
 TaskFactory taskFactory = new TaskFactory();
 taskFactory.ContinueWhenAny(tasks.ToArray(), t =>
 {
 Console.WriteLine($"达到里程碑...  ManagerThreadId={Thread.CurrentThread.ManagedThreadId}");
 });
 
 taskFactory.ContinueWhenAll(tasks.ToArray(), tArray =>
 {
 Console.WriteLine($"项目上线...  ManagerThreadId={Thread.CurrentThread.ManagedThreadId}");
 Console.WriteLine($"项目验收...  ManagerThreadId={Thread.CurrentThread.ManagedThreadId}");
 Console.WriteLine($"支付费用...  ManagerThreadId={Thread.CurrentThread.ManagedThreadId}");
 });
 
 
 
 Task.WaitAny(tasks.ToArray());
 Console.WriteLine("达到里程碑...");
 
 
 
 Task.WaitAll(tasks.ToArray());
 
 
 Console.WriteLine("项目上线...");
 Console.WriteLine("项目验收...");
 Console.WriteLine("支付费用...");
 
 }
 
 | 
多线程安全
如果一段代码,单线程执行和多线程执行结果不一致,就表明由线程安全问题