在Java中使用Executor编写文件
我有一张单子;地图列表。每个映射都以文件名作为键,以文件内容作为值 在上面的列表中,我有超过250万张地图。我的要求是遍历这个列表,并在输出文件夹中创建文件,读取每个映射键和值。所以最后我会有2500万个文件。这需要4个多小时。然后我停止程序。我不知道如果我运行整个2500万条记录的程序需要多少时间 我需要使用多线程优化它在Java中使用Executor编写文件,java,multithreading,executorservice,fork-join,threadpoolexecutor,Java,Multithreading,Executorservice,Fork Join,Threadpoolexecutor,我有一张单子;地图列表。每个映射都以文件名作为键,以文件内容作为值 在上面的列表中,我有超过250万张地图。我的要求是遍历这个列表,并在输出文件夹中创建文件,读取每个映射键和值。所以最后我会有2500万个文件。这需要4个多小时。然后我停止程序。我不知道如果我运行整个2500万条记录的程序需要多少时间 我需要使用多线程优化它 如何使用Java Executors/Fork/Join优化它我有Java 7,如果您在一个磁盘上编写文件,我认为添加更多线程不会有什么帮助。你的程序是IO绑定的,不是CPU
如何使用Java Executors/Fork/Join优化它我有Java 7,如果您在一个磁盘上编写文件,我认为添加更多线程不会有什么帮助。你的程序是IO绑定的,不是CPU密集型的。如果你在一个磁盘上写文件,我认为添加更多线程不会有什么帮助。您的程序是IO绑定的,不是CPU密集型的。您可以使用和实现的类 可以使用和实现的类
并行化可以通过将问题分成尽可能多的子问题来实现。对于列表迭代器,可以迭代子列表:
int nThreads = Runtime.getRuntime().availableProcessors() + 1;
ExecutorService exec = Executors.newFixedThreadPool( nThreads );
int interval = list.size()/parallel.nThreads;
int from = 0;
for( int i = 0; i < nThreads; ++i ) {
int to = ( i == nThreads - 1 ) ? 1000 : from + interval;
exec.submit( new Search( from, to, list ));
from = to;
}
exec.shutdown();
exec.awaitTermination( 1, TimeUnit.DAYS );
并行化可以通过将问题分成尽可能多的子问题来实现。对于列表迭代器,可以迭代子列表:
int nThreads = Runtime.getRuntime().availableProcessors() + 1;
ExecutorService exec = Executors.newFixedThreadPool( nThreads );
int interval = list.size()/parallel.nThreads;
int from = 0;
for( int i = 0; i < nThreads; ++i ) {
int to = ( i == nThreads - 1 ) ? 1000 : from + interval;
exec.submit( new Search( from, to, list ));
from = to;
}
exec.shutdown();
exec.awaitTermination( 1, TimeUnit.DAYS );
需要注意的几件事:
正如@vtheron所说,程序更多的是IO绑定,而不是CPU绑定,因此添加更多的线程,您将在上下文切换中浪费更多的CPU周期,这在这里根本不需要
我猜您当前的基准是4小时内250万,那么当前的实现是什么呢
硬件配置也将对性能改进起到至关重要的作用,考虑一下这个问题。
很少注意的事项:
正如@vtheron所说,程序更多的是IO绑定,而不是CPU绑定,因此添加更多的线程,您将在上下文切换中浪费更多的CPU周期,这在这里根本不需要 我猜您当前的基准是4小时内250万,那么当前的实现是什么呢硬件配置也将在性能改进中起到至关重要的作用,考虑一下这个问题。
这是可能的,但是如果需要4个小时来处理25个文件,那么就有很多预处理可以从多线程中获益,或者这些是大量的文件。但对问题的描述并没有这样说。根据他的描述,他的应用程序只是在列表中迭代,用密钥创建一个文件,并将值作为文件内容输出。这是2500万个250万个文件,不是25Yes。编制该清单需要一些预处理时间。它从数据库中获取记录并将其转换为映射列表。对于获取记录,我使用Spring Batch.OK。但是,在将所有文件写入磁盘之前,您是否对地图列表进行了任何处理?到底什么需要4个小时?从DB中检索+写入文件还是仅写入文件?再次说明:如果需要4小时来遍历列表并创建文件,添加更多线程将不会有帮助。这是可能的,但如果需要4小时来处理25个文件,则可能需要进行大量预处理,这可能得益于多线程,或者这些文件太大。可能是的。但对问题的描述并没有这样说。根据他的描述,他的应用程序只是在列表中迭代,用密钥创建一个文件,并将值作为文件内容输出。这是2500万个250万个文件,不是25Yes。编制该清单需要一些预处理时间。它从数据库中获取记录并将其转换为映射列表。对于获取记录,我使用Spring Batch.OK。但是,在将所有文件写入磁盘之前,您是否对地图列表进行了任何处理?到底什么需要4个小时?从DB中检索+写入文件还是仅写入文件?同样:如果遍历列表并创建文件需要4个小时,那么添加更多线程将无济于事。class Search implements Runnable {
final int from;
final int to;
final List< Map< String, String >> list;
Search( int from, int to, List< Map< String, String >> list ) {
this.from = from;
this.to = to;
this.list = list;
}
@Override
public void run(){
for( int b = from; b < to; ++b ) {
Map< String, String > map = list.get(b);
...
}
}
}