如何使用多线程来加快我的应用程序

时间:2018-02-24 20:43:12

标签: java multithreading list concurrency hashset

我正在迭代一个带有+ - 1500个条目的字符串列表。在每次迭代中,我再次遍历一个字符串列表,但这次有+ - 3500万个条目。申请结果非常完美。但是应用程序需要很长时间(2个多小时)来给我结果。我应该如何构建多线程以使我的应用程序更快?

结果列表的顺序并不重要。

  • 我应该将大列表(3500万个条目)划分为更小的块并通过它们并行进行迭代吗? (我如何确定完美的块数?)
  • 我应该为小型List中的每次迭代启动一个线程吗? (这将创建1500个线程,我想其中很多将运行" parallel")

我的其他选择是什么?

代码表示:

List<String> result = new ArrayList<String>();
for(Iterator<String> i = data1.iterator();i.hasNext();){ //1500 entries
  String val = i.next();
  for(Iterator<String> j = data2.iterator();j.hasNext();){ //35 million entries
    String test = j.next();
    if(val.equals(test)){
      result.add(val);
      break;
    }
  }
}
for(Iterator<String> h = result.iterator();h.hasNext();){
  //write to file
}

更新

在重构我的代码并实现JB Nizet给出的答案后,我的应用程序现在运行得更快。现在只需20秒即可获得相同的结果!没有多线程!

2 个答案:

答案 0 :(得分:3)

您可以使用并行流:

List<String> result = 
    data1.parallelStream()
         .filter(data2::contains)
         .collect(Collectors.toList());

但是,由于您在contains()上呼叫data2 1500次,并且由于contains()对于列表是O(N),因此首先将其转换为HashSet可以使事情更快:{ HashSet上的{1}}是O(1)。您甚至可能不再需要多线程:

contains()

答案 1 :(得分:2)

我也同意你的想法。你现在需要做什么?

  
      
  1. 首先计算系统中的处理器数量。
  2.   
  3. 根据处理器数量拆分您的记录并精确创建该线程数。 (numberofprocessor * 2 max,否则因为线程性能之间的上下文切换会降级)。
  4.   

不要创建不必要的大量线程。这不会加速你的申请。根据处理器数量和系统内存大小,准确检查应创建的线程数。高效的并行处理也取决于您的机器硬件。