AsyncResponse和Java 8并行流问题

时间:2017-10-08 11:53:08

标签: rest parallel-processing java-8 jersey

我正在使用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,有时在客户端检索的列表不会返回所有元素。

让我说我通过30它返回29但有时它确实返回30(请求总是相同)

但如果我只使用 forEach 的普通流,那么它总会返回30个元素。

这是某种错误吗?我可以不在rest api中使用parallelStream

更新

正如尤金所回答的那样,这是一个问题,因为当使用并行流时,多个线程正在将记录添加到arraylist中,这不是线程安全的

溶液 使用Synch集合

Collection<String> resplist = Collections.synchronizedCollection(new ArrayList<String>());

1 个答案:

答案 0 :(得分:3)

据我所知,你在这里依赖副作用:

.forEach(req -> {

            String resp = //some process to get (Always return string)
           resplist.add(resp);
             });

您正在生成多个线程,以将元素添加到非线程安全的集合,例如ArrayList

您应该通过.collect(Collectors.toList())

收集这些内容