)
一、线程优先级ThreadPriority1. 核心原理CPU 采用时间片轮转调度机制线程优先级不决定执行先后顺序只决定获取CPU时间片的概率、执行频率、占用时长。优先级从高到低排序Highest AboveNormal Normal默认 BelowNormal Lowest高优先级线程更容易抢到CPU资源、执行频次更高低优先级线程大概率礼让偶尔执行。2. 独立完整代码private void button1_Click(object sender, EventArgs e) { // 正常优先级 Thread t1 new Thread(ShowThreadInfo); t1.Name 线程1-Normal; t1.Priority ThreadPriority.Normal; // 最低优先级 Thread t2 new Thread(ShowThreadInfo); t2.Name 线程2-Lowest; t2.Priority ThreadPriority.Lowest; // 最高优先级 Thread t3 new Thread(ShowThreadInfo); t3.Name 线程3-Highest; t3.Priority ThreadPriority.Highest; // 低于正常优先级 Thread t4 new Thread(ShowThreadInfo); t4.Name 线程4-BelowNormal; t4.Priority ThreadPriority.BelowNormal; // 高于正常优先级 Thread t5 new Thread(ShowThreadInfo); t5.Name 线程5-AboveNormal; t5.Priority ThreadPriority.AboveNormal; // 统一启动并发抢占CPU t1.Start(); t2.Start(); t3.Start(); t4.Start(); t5.Start(); } // 线程执行方法打印线程信息 public void ShowThreadInfo() { for (int i 0; i 10000; i) { Console.WriteLine($线程名{Thread.CurrentThread.Name}ID{Thread.CurrentThread.ManagedThreadId}状态{Thread.CurrentThread.ThreadState}); } }3. 专属注意事项优先级不保证绝对先后执行只是概率倾斜低优先级线程也可能先执行默认线程优先级为 Normal日常业务无需手动修改禁止滥用最高优先级容易抢占系统资源导致系统卡顿优先级仅作用于同进程内线程无法跨进程抢占CPU二、线程传入多个委托方法多任务封装1. 核心原理利用Action委托封装多个无参无返回值的耗时任务将两个自定义方法传入同一个子线程执行实现代码复用、任务封装。子线程内顺序执行多个委托任务通过 Invoke 安全更新UI。2. 独立完整代码private void button2_Click(object sender, EventArgs e) { // 传入两个自定义耗时任务 RunTwoTask( // 任务1计算求和更新label1 () { int sum 0; for (int i 0; i 10000; i) sum i; // 跨线程安全更新UI Invoke(new Action(() label1.Text sum.ToString())); }, // 任务2计算求和更新label2 () { int sum 0; for (int i 0; i 10000; i) sum i; Invoke(new Action(() label2.Text sum.ToString())); } ); } // 封装方法接收两个委托在子线程执行 public void RunTwoTask(Action task1, Action task2) { Thread t new Thread(() { task1.Invoke(); task2.Invoke(); }); t.Start(); Console.WriteLine(主线程不阻塞直接执行完毕); }3. 专属注意事项多个委托在同一个子线程串行执行不是并发执行子线程严禁直接操作UI必须使用 Invoke 抛回主线程更新Action 委托仅支持无参无返回值方法有参数/返回值需使用 Func该写法适合批量封装耗时任务简化线程创建代码三、lock 线程锁解决多线程资源争抢1. 核心原理多线程同时操作同一个共享变量/资源时会出现数据错乱、数据覆盖问题。lock(锁对象)可以锁住代码块同一时间仅允许一个线程进入执行其他线程排队等待保证共享资源操作的原子性、安全性。2. 独立完整代码// 共享全局变量多线程争抢资源 int sum 0; // 专属锁对象必须唯一、静态、只读 readonly object lockObj new object(); private void button3_Click(object sender, EventArgs e) { // 启动两个线程同时操作sum Thread t1 new Thread(AddSum); Thread t2 new Thread(SubSum); t1.Start(); t2.Start(); } // 线程1累加操作 public void AddSum() { for (int i 0; i 10000; i) { // 锁定代码块单线程独占执行 lock (lockObj) { sum; Console.WriteLine($线程1执行sum {sum}); } } } // 线程2累加操作 public void SubSum() { for (int i 0; i 10000; i) { // 同一把锁排队执行 lock (lockObj) { sum; Console.WriteLine($线程2执行sum {sum}); } } }3. 专属注意事项锁对象必须是全局唯一不能在方法内new否则锁失效多个线程必须使用同一把锁不同锁无法互斥lock 只锁代码块不锁对象仅限制多线程进入锁范围尽量最小化避免锁过多代码导致性能卡顿、变回同步无锁数据错乱有锁数据安全、有序执行四、线程死锁成因、代码、解决方案1. 核心原理死锁成因两个或多个线程互相持有对方需要的锁资源同时互相等待对方释放锁双方僵持不释放线程永久阻塞程序卡死。经典场景线程1持有锁A等待锁B线程2持有锁B等待锁A双方无限等待代码永久卡住2. 死锁错误代码可直接复现卡死private void button4_Click(object sender, EventArgs e) { object lockA new object(); object lockB new object(); // 线程1先拿A锁再拿B锁 new Thread(() { lock (lockA) { Thread.Sleep(100); // 保证线程2先拿到B锁 lock (lockB) { Console.WriteLine(线程1执行完成); } } }).Start(); // 线程2先拿B锁再拿A锁 new Thread(() { lock (lockB) { Thread.Sleep(100); // 保证线程1先拿到A锁 lock (lockA) { Console.WriteLine(线程2执行完成); } } }).Start(); }3. 死锁最优解决方案统一锁的获取顺序所有线程获取多把锁的顺序保持一致从根源杜绝死锁。4. 修正后无死锁代码private void button4_Click(object sender, EventArgs e) { object lockA new object(); object lockB new object(); // 线程1固定顺序 先A后B new Thread(() { lock (lockA) { Thread.Sleep(100); lock (lockB) { Console.WriteLine(线程1执行完成); } } }).Start(); // 线程2和线程1保持一致 先A后B new Thread(() { lock (lockA) { Thread.Sleep(100); lock (lockB) { Console.WriteLine(线程2执行完成); } } }).Start(); }5. 专属注意事项死锁四大必要条件互斥、请求保持、不可剥夺、循环等待最简单高效的解决方式所有线程锁顺序统一禁止多线程交叉嵌套锁极易引发死锁死锁后线程永久阻塞不会自动恢复只能重启程序五、整体知识点总结一、线程优先级不控制执行顺序仅倾斜CPU时间片占用概率二、多委托传参封装多段耗时逻辑单线程串行执行安全更新UI三、lock线程锁保证共享资源原子操作解决多线程数据错乱问题四、线程死锁交叉嵌套锁导致互相等待统一锁顺序即可彻底解决