Ank*_*ani 15 java concurrency file
我想通过10个线程访问一个大文件(文件大小可能从30 MB到1 GB),然后处理文件中的每一行,并通过10个线程将它们写入另一个文件.如果我只使用一个线程来访问IO,则其他线程被阻止.处理花费一些时间几乎相当于从文件系统中读取一行代码.还有一个约束,输出文件中的数据应与输入文件的数据顺序相同.
我想要你对这个系统的设计有所了解.是否有任何现有的API支持并发访问文件?
写入同一文件也可能导致死锁.
如果我关心时间限制,请建议如何实现这一点.
for*_*two 13
我会从三个线程开始.
当然,我还要确保输出文件与输入文件在物理上不同的磁盘上.
如果处理速度往往比I/O(监视队列大小)慢,那么您可以开始尝试两个或多个并行"处理器",这些"处理器"在读取和写入数据方面是同步的.
mik*_*ike 11
该类不应该调度字符串,它应该将它们包装在Line
包含元信息的类中,例如行号,因为您要保留原始序列.
您需要一个处理类,它可以对收集的数据进行实际操作.在你的情况下,没有工作要做.该类只存储信息,您可以在某一天扩展它以执行其他操作(例如,反转字符串.附加一些其他字符串,...)
然后,您需要一个合并类,它在处理线程上执行某种多路合并排序,并按顺序收集对 Line
实例的所有引用.
合并类也可以将数据写回文件,但要保持代码清洁......
当然,如果你缺少主内存,你需要很多内存.你需要一个基于流的方法种的作品就地保留的内存开销很小.
更新基于流的方法
除了以下情况外,保持不变:
该Reader
线程泵将数据读入一个Balloon
.这个气球有一定数量的Line
实例可以容纳(数字越大,消耗的主内存就越多).
加工线程Line
从气球中取出,读取器在更加空气时将更多的线条泵入气球.
merger类从上面的处理线程中获取行,并且writer将数据写回文件.
也许你应该FileChannel
在I/O线程中使用,因为它更适合读取大文件,并且在处理文件时可能消耗更少的内存(但这只是一个估计的猜测).
任何类型的IO,无论是磁盘,网络等,通常都是瓶颈.
通过使用多个线程,您正在加剧问题,因为很可能一次只有一个线程可以访问IO资源.
最好使用一个线程来读取,将信息传递给工作线程池,然后直接从那里写入.但是,如果工人写到同一个地方会再次出现瓶颈,因为只有一个人可以拥有锁.通过将数据传递给单个编写器线程轻松修复.
简而言之":
单个读取器线程写入BlockingQueue等,这给它一个自然有序的序列.
然后工作线程线程在队列上等待数据,记录其序列号.
工作线程然后将处理过的数据写入另一个BlockingQueue,这次附加其原始序列号
写入线程可以获取数据并按顺序写入.
这可能会产生最快的实施.