AsyncResponse和Java 8并行流问题 [英] AsyncResponse and Java 8 parallel stream issue

查看:554
本文介绍了AsyncResponse和Java 8并行流问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆