AsyncResponse 和 Java 8 并行流问题
AsyncResponse and Java 8 parallel stream issue
我正在使用 spring 引导 Jersey rest api
@POST
@Path("test")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public void test(final List<String> requests, @Suspended final AsyncResponse asyncResponse) {
List<String> resplist = new ArrayList();
requests.parallelStream().forEach(req -> {
String resp = //some process to get (Always return string)
resplist.add(resp);
});
asyncResponse.resume(resplist);
}
如果我使用 parallelStream
,有时在客户端检索到的列表不会 return 所有元素。
假设我通过 30 它 returns 29 但有时它会 return 30(请求总是相同的)
但是如果我只使用 forEach
的普通流,那么它总是 return 给我 30 个元素。
这是某种错误吗?我不能在休息时使用 parallelStream api
更新
正如 Eugene 所回答的那样,这是问题所在,因为当使用并行流时,多个线程将记录添加到 arraylist 中,这不是线程安全的
解决方案
使用同步集合
Collection<String> resplist = Collections.synchronizedCollection(new ArrayList<String>());
据我所知,您在这部分依赖于副作用:
.forEach(req -> {
String resp = //some process to get (Always return string)
resplist.add(resp);
});
您正在生成多个线程以将元素添加到非线程安全的集合中,例如 ArrayList
。
您应该通过 .collect(Collectors.toList())
收集这些信息
我正在使用 spring 引导 Jersey rest api
@POST
@Path("test")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public void test(final List<String> requests, @Suspended final AsyncResponse asyncResponse) {
List<String> resplist = new ArrayList();
requests.parallelStream().forEach(req -> {
String resp = //some process to get (Always return string)
resplist.add(resp);
});
asyncResponse.resume(resplist);
}
如果我使用 parallelStream
,有时在客户端检索到的列表不会 return 所有元素。
假设我通过 30 它 returns 29 但有时它会 return 30(请求总是相同的)
但是如果我只使用 forEach
的普通流,那么它总是 return 给我 30 个元素。
这是某种错误吗?我不能在休息时使用 parallelStream api
更新
正如 Eugene 所回答的那样,这是问题所在,因为当使用并行流时,多个线程将记录添加到 arraylist 中,这不是线程安全的
解决方案 使用同步集合
Collection<String> resplist = Collections.synchronizedCollection(new ArrayList<String>());
据我所知,您在这部分依赖于副作用:
.forEach(req -> {
String resp = //some process to get (Always return string)
resplist.add(resp);
});
您正在生成多个线程以将元素添加到非线程安全的集合中,例如 ArrayList
。
您应该通过 .collect(Collectors.toList())