Java 将多个并行对象联接到单个列表中

Java 将多个并行对象联接到单个列表中,java,concurrency,java-stream,Java,Concurrency,Java Stream,我有一个键值图,在键值上迭代,调用服务,根据响应,我将所有响应添加到一些uberList 如何同时执行不同的操作?将stream()更改为parallelStream()会起作用吗?当它添加到uberList时是否同步 这样做的目的是尽可能缩短响应时间 List<MyClass> uberList = new LinkedList<>(); Map<String, List<MyOtherClass>> map = new HashMap();

我有一个键值图,在键值上迭代,调用服务,根据响应,我将所有响应添加到一些
uberList

如何同时执行不同的操作?将
stream()
更改为
parallelStream()
会起作用吗?当它添加到uberList时是否同步

这样做的目的是尽可能缩短响应时间

List<MyClass> uberList = new LinkedList<>();

Map<String, List<MyOtherClass>> map = new HashMap();

//Populate map

map.entrySet().stream().filter(s -> s.getValue().size() > 0 && s.getValue().values().size() > 0).forEach(
   y  -> {

        // Do stuff
        if(noError) {
            uberList.add(MyClass3);
        }

   }

}  

//Do stuff on uberList
List uberList=newlinkedlist();
Map Map=newhashmap();
//填充地图
map.entrySet().stream().filter(s->s.getValue().size()>0&&s.getValue().values().size()>0.forEach(
y->{
//做事
如果(无错误){
uberList.add(MyClass3);
}
}
}  
//做优步列表上的事情

我相信您可以使用并行流和同步映射和列表来完成您所需的任务。

我相信您可以使用并行流和同步映射和列表来完成您所需的任务。

并行流将有助于并行执行。但不建议对每个循环执行操作并在列表外部添加元素。如果您这样做首先,您必须确保同步外部列表。更好的方法是使用映射并将结果收集到列表中。在这种情况下,parallelStream负责同步

List<MyClass> uberList = map.entrySet().parallelStream().filter(s -> 
s.getValue().size() > 0 && s.getValue().values().size() > 
0).map(
y  -> {
    // Do stuff
        return MyClass3;
    }
 }
.filter(t -> check no ertor condition)
.collect (Collectors.toList())
List uberList=map.entrySet().parallelStream().filter(s->
s、 getValue().size()>0&s.getValue().values().size()>
0)地图(
y->{
//做事
返回MyClass3;
}
}
.过滤器(t->检查无故障或条件)
.collect(收集器.toList())

并行流将有助于并行执行。但不建议执行forEach循环并在外部列表中添加元素。如果这样做,您必须确保同步外部列表。更好的方法是使用映射并将结果收集到列表中。在这种情况下,并行流负责同步

List<MyClass> uberList = map.entrySet().parallelStream().filter(s -> 
s.getValue().size() > 0 && s.getValue().values().size() > 
0).map(
y  -> {
    // Do stuff
        return MyClass3;
    }
 }
.filter(t -> check no ertor condition)
.collect (Collectors.toList())
List uberList=map.entrySet().parallelStream().filter(s->
s、 getValue().size()>0&s.getValue().values().size()>
0)地图(
y->{
//做事
返回MyClass3;
}
}
.过滤器(t->检查无故障或条件)
.collect(收集器.toList())

您可能不想使用
parallelStream
来实现并发性,而只是为了实现并行性。(也就是说,如果您希望在一个概念上连续的任务上高效地使用多个物理进程,那么就使用它,而不是在概念上希望同时进行多件事情的任务中使用它。)

在您的情况下,您最好使用google Guava提供的
ExecutorService
,或者更具体地说
com.google.common.util.concurrent.ListenableExecutorService
(警告:我尚未尝试编译以下代码,可能存在语法错误):

int最大同时请求数=100;
ListingExecutor服务myExecutor=
更多执行者、监听器、装饰者(
newFixedThreadPool(最大并发请求数);
列表期货=新的ArrayList();
对于(Map.Entry:Map.entrySet()){
if(entry.getValue().size()>0&&entry.getValue().values().size()>0){
futures.add(myExecutor.submit)(()->{
//做事
如果(无错误){
返回可选的.of(MyClass3);
}否则{
返回可选的.empty();
}
}));
}
}
List uberList=Futures.successfulAsList(Futures)
.get(1,TimeUnit.MINUTES/*根据需要调整*/)
.stream()
.filter(可选::isPresent)
.map(可选::get)
.collect(Collectors.toList());

此代码的优点是,它允许您显式地指定所有任务都应“同时”(至少在概念上)启动,并允许您显式地控制并发性(允许同时请求多少次?如果某些任务失败,我们该怎么办?我们愿意等待多久?等等).并行流并不是真的那样。

您可能不想将
parallelStream
用于并发,而只是用于并行。(也就是说:如果您希望在概念上连续的任务上有效地使用多个物理进程,则将其用于该任务,而不是希望在概念上同时进行多件事情的任务。)

在您的情况下,您最好使用google Guava提供的
ExecutorService
,或者更具体地说
com.google.common.util.concurrent.ListenableExecutorService
(警告:我尚未尝试编译以下代码,可能存在语法错误):

int最大同时请求数=100;
ListingExecutor服务myExecutor=
更多执行者、监听器、装饰者(
newFixedThreadPool(最大并发请求数);
列表期货=新的ArrayList();
对于(Map.Entry:Map.entrySet()){
if(entry.getValue().size()>0&&entry.getValue().values().size()>0){
futures.add(myExecutor.submit)(()->{
//做事
如果(无错误){
返回可选的.of(MyClass3);
}否则{
返回可选的.empty();
}
}));
}
}
List uberList=Futures.successfulAsList(Futures)
.get(1,TimeUnit.MINUTES/*根据需要调整*/)
.stream()
.filter(可选::isPresent)
.map(可选::get)
.collect(Collectors.toList());
此代码的优点是,它允许您显式地指定所有任务都应“同时”(至少在概念上)启动,并允许您显式地控制并发性(允许同时请求多少次?如果某些任务失败,我们该怎么办?我们愿意等待多久?等等).平行流并不是这样的

如何同时执行不同的操作

一个线程一次可以执行一个任务。如果您想同时执行多个操作,则必须将工作转移到其他线程。 您可以创建新线程,也可以使用ExecutorService来管理线程池、对任务排队并执行
uberList = map.entrySet().stream()
                         .parallel()  // Use .stream().parallel() to force parallism. The .parallelStream() does not guarantee that the returned stream is parallel stream
                         .filter(yourCondition)
                         .map(e -> yourService.methodCall(e))
                         .collect(Collectors.toList());
ForkJoinPool forkJoinPool = new ForkJoinPool(4); // Typically set it to Runtime.availableProcessors()
uberlist = forkJoinPool.submit(() -> {
     return map.entrySet().stream()
                             .parallel()  // Use .stream().parallel() to force parallism. The .parallelStream() does not guarantee that the returned stream is parallel stream
                             .filter(yourCondition)
                             .map(e -> yourService.methodCall(e))
                             .collect(Collectors.toList());
}).get();