Java多线程文件处理:读写+BlockingQueue缓存实现方案咨询
问题解答
1. 3个独立SingleThreadExecutor是否等于串行处理?
答案是否定的,二者效率差异非常明显:
- 3个独立的单线程池是并行运行的,各自负责的读、加工、写三个环节互不阻塞:比如加工线程处理某条数据的同时,读线程可以继续读取后续文件内容,写线程也可以同步写入已经加工完成的结果,只要中间队列足够缓冲未处理的数据,整体效率远高于单线程从头到尾串行执行。
- 只有当你把三个环节的逻辑都放到同一个单线程池里执行,才会和串行效果完全一致。
2. 现有代码的问题
你当前贴的代码里ArrayBlockingQueue没有起到作用:你已经把拆分后的valueList直接提交给了executor2的任务,没有走队列存取的逻辑,队列在这里属于冗余实现。
3. 方案优化建议
你的场景属于典型的流水线式生产者-消费者模型,按任务类型拆分不同线程池的思路是完全合理的,不需要强求用同一个FixedThreadPool处理所有任务,反而拆分后更方便针对不同环节做调优:
- 保留两个阻塞队列:一个存读取到的原始待加工数据(读线程是生产者,加工线程是消费者),另一个存加工完成的待写入结果(加工线程是生产者,写线程是消费者)
- 读环节:用单线程即可,毕竟磁盘IO多线程读同个文件不会有明显收益,读取到的每条拆分后的数据直接塞原始数据队列
- 加工环节:如果加工逻辑是CPU密集型,把executor2换成
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())即可,所有加工线程只负责从原始数据队列拉取数据、加工、把结果塞结果队列,完全不用关心读写逻辑 - 写环节:保持单线程即可,避免多线程写文件的并发冲突和锁开销,只负责从结果队列拉数据写入目标文件
调整后你既可以通过调整加工线程的数量控制整体处理效率,也能完全区分不同类型任务的执行逻辑,不会出现任务类型混淆的问题。
内容的提问来源于stack exchange,提问作者Raghav
相关产品推荐
相关产品推荐

