Java 将变量传递给ExecutorService';未来

Java 将变量传递给ExecutorService';未来,java,concurrency,Java,Concurrency,我想重构以下代码 Set<String> allStrings ... Set<MyTask> myTasks = ... myTasks.add(new MyTask()); myTasks.add(new MyTask()); ... List<Future<Set<String>>> futures = executorService.invokeAll(myTasks); executorService.shutdown();

我想重构以下代码

Set<String> allStrings ...
Set<MyTask> myTasks = ...
myTasks.add(new MyTask());
myTasks.add(new MyTask());
...
List<Future<Set<String>>> futures = executorService.invokeAll(myTasks);
executorService.shutdown();
for (Future<Set<String>> future : futures) {
    Set<String> strings = future.get();
    allStrings.addAll(strings);
}
// do stuff with allStrings
....
这样做可以吗?由于结果似乎不同(在我的实际代码中,而不是在这段代码中),我是否需要担心并发性问题

另外,我是否可以假设所有任务都已完成,这样我就不必在使用
allStrings
执行操作之前进行虚拟循环:

for (Future<Set<String>> future : futures) {
    future.get();
}
// do stuff with `allStrings`
for(未来:未来){
future.get();
}
//用'allStrings'做东西`

这里您唯一应该担心的是并发访问此
allString
集合


因此,根据在这个线程中(在
MyTask
中)所做的事情,您应该选择适当的
Set
同步实现;你可以在这里读到哪一个:

@Andemoniy假设我在
MyTask
中所做的一切都是添加到
allStrings
,而不删除任何内容,同步是否应该成为问题?@FaizalKamarrudin是的。添加到
集合
是一项复杂的操作。如果实现是一个
哈希集
,那么添加操作将涉及从哈希表bucket读取链表引用,然后修改列表和/或bucket。如果两个任务试图同时添加具有相同哈希索引的两个对象,它们将同时尝试更新相同的链表,结果将是一场灾难。@ajb不知道这一点。谢谢
for (Future<Set<String>> future : futures) {
    future.get();
}
// do stuff with `allStrings`