AsyncResponse和Java 8并行流问题 [英] AsyncResponse and Java 8 parallel stream issue
问题描述
我正在使用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
,则有时在客户端检索的列表不会返回所有元素.
If I use parallelStream
sometimes the list that is retrieved on the client side does not return all the elements.
让我们说我通过30会返回29,但有时会返回30(请求始终相同)
Lets say I pass 30 it returns 29 but sometime it does return 30 (Request is always the same)
但是如果我仅将普通流与 forEach
一起使用,那么它总是返回30个元素.
But If I use normal stream with forEach
only, then it always returns me 30 elements.
这是某种错误吗?我能否在rest api中不使用parallelStream
Is this some sort of bug? Can I not use parallelStream in rest api
更新
正如Eugene回答的那样,这是一个问题,因为在使用并行流时,多个线程正在将记录添加到不是线程安全的arraylist中
As answered by Eugene this was the issue because when using parallel stream multiple threads were adding record into arraylist which is not threadsafe
解决方案 使用同步收集
Collection<String> resplist = Collections.synchronizedCollection(new ArrayList<String>());
推荐答案
据我所知,您在此部分依赖副作用:
As far as I can see you are relying on side-effects here in the part:
.forEach(req -> {
String resp = //some process to get (Always return string)
resplist.add(resp);
});
您正在生成多个线程,以将元素添加到非线程安全的集合中,例如ArrayList
.
You are spawning multiple threads to add elements to a non-thread-safe collection such as ArrayList
.
您应该改为通过.collect(Collectors.toList())
这篇关于AsyncResponse和Java 8并行流问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!