0

I apologize if this already has been answered, I can't seem to find it. I did see this. We are using springboot 2.3.1.RELEASE, jdk 1.8, tomcat-dbcp 8.5.11. We are having a lot of records that we're trying to retrieve and save to the database and we're using CompletableFuture for that.

I see this stack trace once I terminate the application after it has completed its run:

The web application [ROOT] appears to have started a thread named [pool-35-thread-12] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await
(AbstractQueuedSynchronizer.java:2044)
java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)

The code:

 for(String department : departmentList) 
 {
    Executor executor = Executors.newFixedThreadPool(20);
    // Some logic to get deptKeyLists which is List<List<Long>>
    for(List<Long> deptKeyList: deptKeyLists)
     {
         // A REST call to get item information within the department
             for(ItemContainerDTO itemContainerDTO : data.getBody().getItemContainer())
                 {
                     for(ItemDTO itemDTO : itemContainerDTO.getItems())
                     {
                         futureList.add(CompletableFuture.supplyAsync(() ->
                         service.saveDataToDB(requestId, itemContainerDTO, 
                                 itemDTO), executor)
                                 .exceptionally(exception -> {
                                        log.error("Exception occurred for requestId - {}", requestId);
                                        
                                        return null;
                                 }));
                     }
                 }
                 futureList.stream()
                 .filter(f1 -> !f1.isCompletedExceptionally())
                 .map(CompletableFuture::join).forEach(f -> log.info("RequestId : {}, Total {}", requestId , f));
    }
 }. 

Any suggestions/recommendations on why this could be occurring?

Thanks

linuxNoob
  • 600
  • 2
  • 14
  • 30
  • you are creating an executor _inside_ the loop? – Eugene May 06 '21 at 19:04
  • Should it always be outside the loop? I'm not super familiar with the intricacies of threading or `CompletableFuture` plus this is pre-existing code. – linuxNoob May 06 '21 at 19:54
  • yeah, I mean you are creating a pool of `20 threads` for _each_ department. all the time. – Eugene May 06 '21 at 19:56
  • @Eugene moved it outside the loop but still see the same stack trace. – linuxNoob May 06 '21 at 20:02
  • can you make it a `private static final ....`, so that it is common for all code and decrease the number of threads inside it? – Eugene May 06 '21 at 20:07
  • I only have 1 department right now so I don't think it is the cause of the issue. I can't make it a constant because the the number is being read from the cloud. I just put 20 here to simplify it. – linuxNoob May 06 '21 at 20:24

0 Answers0