Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AsyncResponse and Java 8 parallel stream issue

I am using spring boot with 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);

}

If I use parallelStream sometimes the list that is retrieved on the client side does not return all the elements.

Lets say I pass 30 it returns 29 but sometime it does return 30 (Request is always the same)

But If I use normal stream with forEach only, then it always returns me 30 elements.

Is this some sort of bug? Can I not use parallelStream in rest api

UPDATE

As answered by Eugene this was the issue because when using parallel stream multiple threads were adding record into arraylist which is not threadsafe

solution Use Synch collection

Collection<String> resplist = Collections.synchronizedCollection(new ArrayList<String>());
like image 948
Makky Avatar asked Aug 05 '26 14:08

Makky


1 Answers

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);
             });

You are spawning multiple threads to add elements to a non-thread-safe collection such as ArrayList.

You should instead collect those via .collect(Collectors.toList())

like image 149
Eugene Avatar answered Aug 08 '26 20:08

Eugene



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!