【发布时间】:2018-06-13 00:35:11
【问题描述】:
前提条件(通用描述):
1.静态类字段
static List<String> ids = new ArrayList<>();
2. CompletableFuture#runAsync(Runnable runnable,Executor executor)
在内部调用
static void main(String args[])方法
3. 元素添加到来自 step2
的runAsync 调用内部的 someCollection
代码sn -p (具体说明):
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>?
【问题讨论】:
-
停止使用可变静态变量。可变静态是邪恶的!!!
-
除了@lance-java 所说的之外,您的问题实际上是
ArrayList不是线程安全的,并且您没有任何同步来访问它。所以你正在破坏它的内部数据结构。 -
@DidierL 谢谢你的提示,我已经开始使用
ConcurrentSkipListSet<String>看起来可以吗? -
我不知道你的要求,但你应该看看Is there a concurrent List in Java's JDK?。
ConcurrentLinkedQueue可能更合适。 -
@DidierL 谢谢,我会调查一下
标签: java static field updating completable-future