Java 8方法参数列表的并行流

时间:2019-03-11 15:56:58

标签: java java-8 parallel-processing java-stream

我有一个方法:

 protected void Page_Load(object sender, EventArgs e)
 {
     ...
     selected_tab.Value = Request.Form[selected_tab.UniqueID];
     ...
 }

此方法在jar中,我无法访问它的源代码。因此,我需要以并行方式执行invokList,有人可以为此提供帮助吗?

想法是将列表分为多个列表并并行执行invokList。

我已经举了这个例子:

invokList(List<Object> list);

3 个答案:

答案 0 :(得分:5)

番石榴具有方法Lists.partitionIterables.partition,它们的作用类似于您所要求的。假设您有一个很大的列表,并希望以5个为大块进行处理,则可以执行以下操作:

int batchSize = 5;
Lists.partition(list, batchSize)
   .parallelStream()
   .forEach(batch -> invokeList(batch));

答案 1 :(得分:1)

看起来很冗长,但是您可以尝试以下方法。 A->B->A方法将使列表块并行运行。

runAsync()

我将其运行为包含30个整数的列表,其块大小为5 如下:

private void test(List<Object> list, int chunkSize) throws ExecutionException, InterruptedException {
    AtomicInteger prev = new AtomicInteger(0);
    List<CompletableFuture> futures = new ArrayList<>();
    IntStream.range(1, (int) (chunkSize * (Math.ceil(Math.abs(list.size() / (double) chunkSize)))))
            .filter(i -> i % chunkSize == 0 || i == list.size())
            .forEach(i -> {
                List<Object> chunk = list.subList(prev.get(), i);
                futures.add(CompletableFuture.runAsync(() -> invokeList(chunk)));
                prev.set(i);
            });
    CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get();
}

private void invokeList(List<Object> list) {
    System.out.println("Invoked for: " + list);
}

输出

public static void main(String[] args) throws ExecutionException, InterruptedException {
    List<Object> list = IntStream.range(0, 30).mapToObj(i1 -> (Object) String.valueOf(i1)).collect(Collectors.toList());
    int chunkSize = 5;
    new Test().test(list, chunkSize);
}

答案 2 :(得分:1)

如果您不想带来诸如Guava之类的其他依赖项,则可以编写一个收集器,将您的列表分成多个块:

static <T> Collector<T, List<List<T>>, List<List<T>>> toChunks(int size) {
    return Collector.of(ArrayList::new, (list, value) -> {
        List<T> chunk = list.isEmpty() ? null : list.get(list.size() - 1);
        if (chunk == null || chunk.size() == size) {
            chunk = new ArrayList<>(size);
            list.add(chunk);
        }
        chunk.add(value);
    }, (list1, list2) -> {
        throw new UnsupportedOperationException();
    });
}

,然后按以下方式调用它:

 List<Integer> list = Arrays.asList(1,26,17,18,19,20);
 list.stream().collect(toChunks(5))
              .parallelStream()
              .forEach(System.out::println);