gpt4 book ai didi

java - CompletableFuture 中的静态集合更新#runAsync

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:46:11 26 4
gpt4 key购买 nike

先决条件(一般描述):

1.静态类字段

static List<String> ids = new ArrayList<>();

2. CompletableFuture#runAsync(Runnable runnable,Executor executor)

在内部调用 static void main(String args[])方法

3. 元素添加到 someCollection runAsync 内部从step2

调用

代码片段(具体描述):

private static List<String> ids = new ArrayList<>();

public static void main(String[] args) throws ExecutionException, InterruptedException {
//...
final List<String> lines = Files.lines(path).collect(Collectors.toList());
for (List<String> lines : CollectionUtils.split(1024, lines)) {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
List<User> users = buildUsers();
populate(users);
}, executorService);

futures.add(future);
}

private static void populate(List<User> users){
//...
ids.add(User.getId);
//...
}
}

问题描述:

据我了解,从并发的角度来看,静态变量不能在线程之间共享,因此数据可能会以某种方式丢失。

是否应该改为volatile或者使用是合理的 ConcurrentSkipListSet<String>

最佳答案

基于代码片段:

  • volatile 在这里不是必需的,因为它在引用级别上工作,而任务不会更新集合对象的引用,它们会改变其状态。如果引用被更新,可能已经使用了 volatileAtomicReference

  • 静态对象可以在线程间共享,但对象必须是线程安全的。并发收集将完成轻度到中度负载的工作。

但现代的方法是使用流而不是使用共享集合:

List<CompletableFuture<List<String>>> futures = lines.stream()
.map(line -> CompletableFuture.supplyAsync(() -> buildUsers().stream()
.map(User::getId)
.collect(Collectors.toList()),
executorService))
.collect(Collectors.toList());

ids.addAll(futures.stream()
.map(CompletableFuture::join)
.flatMap(List::stream)
.collect(Collectors.toList()));

关于java - CompletableFuture 中的静态集合更新#runAsync,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48075628/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com