Search code examples
javamultithreadingspring-bootjava-iooutputstream

Streaming data on same outputStream in multiple threads


I am creating a spring boot application which connects to multiple REST services and write the responses on outputStream. I am also using multiple threads to call the REST services.

 public ResponseEntity<StreamingResponseBody> startBombing(Request request) {
        int numberOfThreads = request.getConfig().getNumberOfThreads() ==0?5:request.getConfig().getNumberOfThreads();

         long requestPerThread = request.getConfig().getRequestPerThread() ==0 ? 100: request.getConfig().getRequestPerThread();



        StreamingResponseBody responseBody = response -> {
            for (int i = 1; i <= numberOfThreads; i++) {
                int finalI = i;
                Runnable r1 = () -> {
                    try {
                        for (int j = 1; j <= requestPerThread; j++) {
                            HttpRequest req = createRequest(request.getHttpRequest());
                            Object res = doRequest(req);

                            System.out.println("Thread number: " + finalI + ": " + "call number: " + j + "TimeStamp: " + System.currentTimeMillis() + ":::: RESPONSE: " + res);
                            response.write(("Thread number: " + finalI + ": " + "call number: " + j + "TimeStamp: " + System.currentTimeMillis() + ":::: RESPONSE: " + res).getBytes());

                        }
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                };

                Thread t1 = new Thread(r1);
                t1.start();
            }
        };
        return ResponseEntity.ok()
                .contentType(MediaType.TEXT_PLAIN)
                .body(responseBody);
    }

No data is printed on the output stream.

Any clue how to reuse same outputStream in muliple threads


Solution

  • Wait for all threads to finish before exiting lambda (as it will close the output for you)

    StreamingResponseBody responseBody = response -> {
            CountDownLatch latch=new CountDownLatch(numberOfThreads);
            for (int i = 1; i <= numberOfThreads; i++) {
                int finalI = i;
                Runnable r1 = () -> {
                    try {
                        //ireelevant code
                    } finally{
                        latch.countDown(); // decrease latch counter
                    }
                };
    
                Thread t1 = new Thread(r1);
                t1.start();
            }
         latch.await(); // wait for latch to count down to 0 + add error handling and return value
        };