当前位置: 首页 > news >正文

C# 多线程进阶知识点(线程优先级、多委托传参、线程锁、死锁)

一、线程优先级(ThreadPriority)

1. 核心原理

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线程锁:保证共享资源原子操作,解决多线程数据错乱问题

  • 四、线程死锁:交叉嵌套锁导致互相等待,统一锁顺序即可彻底解决

http://www.jsqmd.com/news/1204882/

相关文章:

  • Liunx内核IO多路复用selector机制简介
  • 梁山派学习笔记1
  • 宝珀官方售后服务中心电话和完整地址实地考察报告_多信源验证(2026年7月更新) - 宝珀官方售后服务中心
  • 文件夹加密实战指南:从AES原理到EFS、BitLocker与VeraCrypt方案选择
  • 从冰冷的对话框到“会说话的脸“:3D数字人交互技术的落地实践
  • VMware虚拟机磁盘扩容与LVM分区管理实战
  • Ubuntu 14.04 LTS 系统安装与优化指南
  • Python新手入门:从Hello World到调试技巧
  • LangServe革新LLM应用部署:从LangChain链到生产级API的一站式方案
  • 2026 年现阶段,鄯善热门的中央空调安装定做厂家哪个好,安装不当?省钱的秘密藏在这套系统里 - 企业推荐管【认证】
  • Windows服务化运行与shawl工具实战指南
  • 大模型自动评分系统:三种方法、四大缺陷与实战应对策略
  • HarmonyOS7 图标按钮行:用 Row 把图文按钮做得更顺手
  • Linux与Windows虚拟机环境搭建与优化指南
  • 普通烤火罩容易起火,新 e 选安全吗?
  • Selenium框架内网页源码获取:iframe与SPA动态内容实战指南
  • HarmonyOS7 加载状态展示页实战:LoadingProgress 不只是会用,还要用得顺手
  • C++异常处理:从基础语法到RAII与noexcept实战指南
  • 从数组逆向搜索到文件加密:Java实战编程与数据安全入门
  • Claude企业版协作功能解析:项目可见性与团队AI知识库管理
  • python3GUI--使用PyQt5仿飞车登录界面(详细图文介绍)
  • Waveloom:本地化AI编程助手,终端环境下的代码智能辅助方案
  • macOS系统降级完整指南与常见问题解决
  • 谷歌云AI工具Kubeflow Pipelines与AI Hub深度解析
  • FPGA阵列相机系统设计与实时4K视频处理
  • MacBook外接显示器时如何有效关闭内屏
  • 云服务官方域名滥用钓鱼攻击深度解析与防御实战
  • Kali Linux基础设置与优化全攻略
  • 量化交易系统构建指南:从策略开发到实盘部署的技术实践
  • 从零实现MINIX文件系统解析器:深入理解磁盘数据组织原理