如何实现相同参数线程串行执行、不同参数线程并行执行?
实现相同参数串行、不同参数并行的线程处理方案
问题描述
现有一段C#代码,线程方法Method1会修改传入的Class1对象,要求:
- 同一个
Class1对象的处理必须串行(不能被多个线程同时修改,避免并发冲突) - 不同的
Class1对象可以并行处理(最大化执行效率)
同时想确认:是否需要在新建并启动线程前,逐个检查是否已有处理相同参数的线程?
原代码如下:
class Class1 { // something } private void Form1_Load(object sender, EventArgs e) { List<Class1> _List = new(); for (int i = 0; i < 10; i++) { _List.Add(new Class1 { }); } for (int i = 0; i < 10; i++) { Thread _Thread = new(Method1); _Thread.Start(_List[new Random().Next(10)]); // 可能连续选中同一个List元素 } } void Method1(object _Object) { // 修改传入的_Object }
解决方案
不需要手动逐个检查线程状态,推荐使用基于对象的专属锁+线程池的方案,既满足并发需求又避免手动管理线程的麻烦。
核心思路
- 为每个
Class1对象分配一个专属的锁对象,确保同一对象的处理请求会排队等待,不同对象的锁互不干扰,实现细粒度并发控制。 - 用
ConcurrentDictionary<Class1, object>存储每个对象对应的锁,它是线程安全的集合,适合多线程环境下存取锁对象。 - 替换手动创建
Thread的方式,改用Task.Run(基于.NET线程池),比手动创建线程更高效、易管理。
修改后的代码示例
using System.Collections.Concurrent; class Class1 { // 类成员 } // 类级的线程安全锁字典,存储每个Class1对象对应的锁 private readonly ConcurrentDictionary<Class1, object> _objectLocks = new ConcurrentDictionary<Class1, object>(); private void Form1_Load(object sender, EventArgs e) { List<Class1> _List = new List<Class1>(); for (int i = 0; i < 10; i++) { _List.Add(new Class1()); } // 把Random实例提到循环外,避免因系统时钟精度问题生成重复随机数 var random = new Random(); for (int i = 0; i < 10; i++) { var targetObj = _List[random.Next(10)]; // 用Task.Run启动异步处理,自动利用线程池 _ = ProcessClass1Async(targetObj); } } // 包装处理逻辑,加入锁保护 async Task ProcessClass1Async(Class1 obj) { // 获取当前对象的专属锁,不存在则自动创建 var lockObj = _objectLocks.GetOrAdd(obj, _ => new object()); // 同一obj的lock块会串行执行,不同obj的lock块并行执行 lock (lockObj) { Method1(obj); } // 可选:如果该obj后续不再被处理,可以移除锁对象释放内存 // _objectLocks.TryRemove(obj, out _); } void Method1(Class1 _Object) { // 原有的修改逻辑,现在已被lock保护,不会出现并发修改问题 }
关键说明
- 无需手动检查线程:
lock关键字会自动对同一锁对象的请求进行排队,底层已经处理了线程同步逻辑,不需要自己跟踪线程状态。 - 锁粒度控制:每个
Class1对象对应一个锁,实现了最小粒度的并发控制,既保证同一对象的串行安全,又不影响其他对象的并行处理。 - 线程池优势:
Task.Run复用线程池中的线程,避免频繁创建销毁线程的性能开销,同时.NET会自动管理线程数量,防止资源耗尽。 - Random的坑:原代码在循环中每次新建
Random,会因为系统时钟的精度问题导致生成重复的随机数,所以必须把Random实例放到循环外。
内容的提问来源于stack exchange,提问作者SHIN JaeGuk
相关产品推荐
相关产品推荐

