有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用多线程使我的应用程序更快

我正在遍历一个包含+-1500个条目的字符串列表。在每次迭代中,我都会再次遍历字符串列表,但这次是+-3500万个条目。应用效果良好。但是应用程序需要很长时间(2个多小时)才能给出结果。我应该如何构造多线程以使我的应用程序更快

结果列表的顺序并不重要

  • 我是否应该将大列表(3500万个条目)划分为较小的块,并并行遍历它们?(如何确定块的完美数量?)
  • 我应该为小列表中的每个迭代启动一个线程吗?(这将创建1500个线程,我猜其中很多线程将“并行”运行)

我的其他选择是什么

守则的表述:

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) 个答案

  1. # 1 楼答案

    您可以使用并行流:

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

    但是,由于您对data2调用了contains()1500次,并且contains()对于列表是O(N),因此首先将其转换为哈希集可以使速度更快:contains()对于哈希集是O(1)。您甚至可能不再需要多线程:

    Set<String> data2Set = new HashSet<>(data2);
    List<String> result = 
        data.stream()
            .filter(data2Set::contains)
            .collect(Collectors.toList());
    
  2. # 2 楼答案

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

    1. First calculate number of processor in your system.
    2. Based on number of processor split your records and create exactly that number of threads. ( numberofprocessor * 2 max, else because of context switching between thread performance will be degraded ).

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