Parallel.For设置10万次循环仅执行100次即终止?技术求助
解决并行循环仅执行100次的诡异问题
嘿,你这情况明显是多线程共享变量的坑没避开!6个线程跑10万次循环,结果总共只执行100次,结合你提到的ProxyWorker里的静态_proxyCount和ConcurrentQueue,我给你拆解几个最可能的原因和解决办法:
1. 静态_proxyCount成了“全局刹车”
静态变量是所有线程共享的,如果你的循环里用它做了终止判断(比如if (_proxyCount >= 100) break;),那6个线程会同时往这个变量上累加,瞬间就冲到100,所有线程直接跳出循环,总执行量自然就只有100次。
比如你大概率写了类似这样的代码:
public void run() { for (int i = 0; i < 100000; i++) { if (_proxyCount >= 100) { break; } // 从队列取数据处理 _proxyCount++; } }
这种写法完全错误,共享的普通静态int不仅线程不安全(++不是原子操作),还会直接把所有线程的循环都掐断在100次。
2. 循环条件被共享变量偷偷修改
虽然你写的是for (int i = 0; i < 100000; i++),但如果循环内部有其他共享变量在控制终止(比如全局开关、依赖_proxyCount的判断),也会导致所有线程提前退出。比如有人误把循环上限改成了_proxyCount < 100,那结果就是总执行100次。
3. 队列消费逻辑藏了限制
你说队列有100万条数据没问题,但如果消费时用_proxyCount做了限制,比如:
long data = queue.poll(); if (data == null || _proxyCount >= 100) { return; } _proxyCount++; // 处理数据
那同样会因为共享变量快速触达阈值,导致所有线程停止处理。
怎么修复?
- 如果每个线程需要独立计数:把
_proxyCount改成ThreadLocal<Integer>,每个线程维护自己的计数器,互相不干扰。 - 如果需要全局统计但不限制执行次数:用
AtomicInteger替代普通静态int,它的incrementAndGet()是线程安全的,不会出现计数混乱,也不会误终止循环。示例:
private static AtomicInteger proxyCount = new AtomicInteger(0); public void run() { for (int i = 0; i < 100000; i++) { long data = queue.poll(); if (data == null) { // 队列空了可以继续等或者跳过,别直接退出循环 continue; } // 处理数据 proxyCount.incrementAndGet(); // 线程安全的全局计数 } }
- 检查所有终止条件:确保每个线程的
for循环i < 100000是独立生效的,没有被其他共享变量偷偷篡改或打断。
这样调整后,6个线程都会各自跑完10万次循环(只要队列数据足够),总执行量就能达到预期的60万次啦。
内容的提问来源于stack exchange,提问作者boxiyiwaj
相关产品推荐
相关产品推荐

