在java中的多线程场景中列出更新

时间:2012-07-18 16:10:26

标签: java multithreading list synchronization

我有一个场景,我需要对非常大的List(例如9000+)条目进行一些处理,然后将处理后的条目添加到新列表中。所以要做到这一点,我采用多线程方法。

在以下两种方式中,哪种方式更有效:

  1. 我应该为每个线程提供单独的列表对象,然后将所有线程的结果添加到一个最终列表中。
  2. 我应该使用同步列表并允许所有线程同时添加到此列表中。

2 个答案:

答案 0 :(得分:2)

线程在可以独立工作时效果最佳。我赞成给每个线程自己的工作,并在完成后收集结果。

在此示例中,每个线程独立工作。

ExecutorService service = 
List<Work> workList = 
int blockSize = (workList.size() + threads -1)/threads;
List<Future<List<Results>>> futureResults = new ArrayList<>();
for(int i=0;i<threads;i++) {
    int start = i * blockSize;
    int end = Math.min(workList.size(), (i + 1) * blockSize);
    final List<Work> list2 = worksList.subList(start, end);
    futureResults.add(service.submit(new Callable<List<Results>>() {
        public List<Results> call() {
             return process(list2);
        }
     });
 }
 List<Results> results = new ArrayList<>();
 for(Future<List<Results>> future:futureResults) 
     results.addAll(future.get()); 

答案 1 :(得分:1)

为什么你认为线程是一个解决方案,你真的没有列出并发解决的问题?

在盛大的计划中,9000个条目并不是很多要处理的事情。如果您已经说过,900万个条目和每个条目需要10秒钟来处理,这可能是另一回事。

除非处理每个事情花费很长时间(相对)并且 CPU绑定(比如在远程机器上等待做某事),我会说在这种情况下多线程不是'我会给你一些不必要的复杂性。

即使处理时间很长,线程也意味着共享数据,从您提供的非常稀疏的模糊信息中,使用来自Queue的{​​{1}}可以更好地使用简单的异步方法。