1

我有一个List<Map<String,String>>ie;地图列表。每个 Map 都有File NameasKeyFile Contentas Value

我在上面的列表中有超过 250 万张地图。我的要求是遍历此列表并在读取每个 Map 键和值的输出文件夹中创建文件。所以最后我将拥有 250 万个文件。需要4个多小时。然后我停止程序。如果我为整个 250 万条记录运行该程序,我不知道确切的时间。

我需要使用多线程对此进行优化。

如何使用 Java 优化它Executors/ Fork/ Join(我有Java 7

4

4 回答 4

4

如果您在单个磁盘上写入文件,我认为添加更多线程不会真正有帮助。您的程序是 IO 密集型的,而不是 CPU 密集型的。

于 2013-04-10T19:35:17.067 回答
0

有几点需要注意:

正如@vtheron 所说,“程序更多的是 IO 限制而不是 CPU 限制”,因此添加更多线程,您将在上下文切换中浪费更多 CPU 周期,这在此处根本不需要。

我猜你当前的基准是 4 小时内 250 万,那么当前的实现是什么?

硬件配置也会对性能提升起到至关重要的作用,考虑看看这个。

于 2013-04-10T19:52:06.753 回答
0

您可以使用ThreadPoolExecutor和实现Runnable的类。

public class Processor implements Runnable {
    private final Map<String, String> map;

    public Processor(Map<String, String> map) {
        this.map = map;
    }

    public void run() {
        // Do work here
    }
}

ThreadPoolExecutor executor = new ThreadPoolExecutor();
for(Map<String, String> map : list) {
    executor.execute(new Processor(map));
}
于 2013-04-10T19:36:12.520 回答
0

可以通过将问题拆分为与可用处理器一样多的子问题来实现并行化。对于列表迭代器,您可以迭代子列表:

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 );

该类Search用于完成工作(创建文件)。

类的例子Search

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);
        ...
     }
  }
}
于 2013-04-10T19:37:39.783 回答