如何让Parallel.For每约200次迭代才锁定调用_printConcurrent而非每次?
解决方案
你可以通过原子操作计数器结合条件判断来实现每200次迭代调用一次_printConcurrent,既保证线程安全,又避免不必要的锁开销。具体实现如下:
int counter = 0; var lockTarget = new object(); Parallel.For(1, totalSIM, i => { /* do some stuff */ // 原子递增计数器,避免多线程冲突 int currentCount = Interlocked.Increment(ref counter); // 每完成200次迭代触发一次监控输出 if (currentCount % 200 == 0) { lock(lockTarget) { _printConcurrent(currentCount); } } }); // 循环结束后补充输出最终状态(可选,避免最后一批不足200次的迭代无监控记录) lock(lockTarget) { _printConcurrent(counter); }
逻辑说明
- 原子递增:用
Interlocked.Increment替代普通的counter++,确保并行环境下计数器的递增操作线程安全,无需每次都加锁。 - 条件触发:每次递增后检查当前计数是否为200的倍数,满足条件时才进入锁块调用
_printConcurrent,减少锁的使用频率。 - 最终补充输出:如果总迭代数不是200的整数倍,循环结束后额外调用一次
_printConcurrent,保证最终的监控数据能被输出。
如果_printConcurrent本身已实现线程安全(比如内部做了同步处理),可以去掉锁块直接调用,但保留锁能确保监控日志的有序性,避免输出混乱。
内容的提问来源于stack exchange,提问作者Leandro Bardelli
相关产品推荐
相关产品推荐

