我有一个方法:
protected void Page_Load(object sender, EventArgs e)
{
...
selected_tab.Value = Request.Form[selected_tab.UniqueID];
...
}
此方法在jar中,我无法访问它的源代码。因此,我需要以并行方式执行invokList,有人可以为此提供帮助吗?
想法是将列表分为多个列表并并行执行invokList。
我已经举了这个例子:
invokList(List<Object> list);
答案 0 :(得分:5)
番石榴具有方法Lists.partition和Iterables.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);