Threads scheduled with ThreadPoolTaskExecutor keep on running

Hi,
I have the following file :

package com.yatra.extremesearch.app;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.yatra.extremesearch.job.ExtremeSearchJob;



public class ExtremeSearchApp {
	private static final Logger logger = Logger.getLogger(ExtremeSearchApp.class);
	
	public static void main(String args[]){
		
		 try {
			 logger.info("=====Starting Extreme search======");
			 ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring/root-context.xml");
			 ExtremeSearchJob eJob = (ExtremeSearchJob) context.getBean("extremeSearchJob");
			 eJob.execute();
			
			} catch (Exception e) {
				logger.error(e.getMessage());
			}
		}
}

Open in new window


There is the following piece of code in another file which creates threads :
@Autowired @Qualifier("yatraExecutorService") ThreadPoolTaskExecutor yatraExecutorService;
CountDownLatch countDownLatch = new CountDownLatch(params.size());
		for (ExtremeSearchParam param : params) {
			SearchTask task = new SearchTask(this,param,parentFolder,countDownLatch);
			yatraExecutorService.submit(task);	
		}

Open in new window



The SearchTask.java file is as follows :
package com.yatra.extremesearch.service;

import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;

import com.yatra.extremesearch.model.ExtremeSearchParam;

@SuppressWarnings("rawtypes")
public class SearchTask implements Callable{
	ExtremeSearchParam param;
	SearchParamService searchParamService;
	String parentFolder;
	CountDownLatch countDownLatch;
	
	public SearchTask(SearchParamService searchParamService, ExtremeSearchParam param, String parentFolder, CountDownLatch countDownLatch) {
		this.param=param;
		this.searchParamService=searchParamService;
		this.parentFolder=parentFolder;
		this.countDownLatch = countDownLatch;
	}
	
	@Override
	public Object call() throws Exception {
		try{
			searchParamService.processExtremeSearchResp(param,parentFolder);
			return null;
		}finally{
			countDownLatch.countDown();
		}
	}

}

Open in new window


There are some threads created by this java application. But when the tasks are completed i see the threads still running in my debug panel and the program also doesnot exits.

How can i exit the program properly once the tasks are done and why the threads are in running mode even though the code part is over ?

Thanks
Rohit BajajAsked:
Who is Participating?
 
CEHJConnect With a Mentor Commented:
Do you shut down the ThreadPoolTaskExecutor? If you don't, it's mostly likely to have runnable threads
0
 
ValeriCommented:
change the following lin in this way:

public class SearchTask implements Callable<String> {

and the method in this way:

@Override
public Object call() throws Exception {
  try {
     searchParamService.processExtremeSearchResp(param,parentFolder);
  } finally {
     countDownLatch.countDown();
  }
  System.out.println("finished");
  return "finished";
}

if you get string "finished" in console as many times as your threads are then they must complete.
Also I cannot see where is "await" method of your CountDownLatch?
0
 
mccarlConnect With a Mentor IT Business Systems Analyst / Software DeveloperCommented:
Along the lines of CEHJ's comment above, to get Spring to shutdown the TaskExecutor, try changing line 18 of the first snippet above (the line that creates your app context) to these two lines...
            ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring/root-context.xml");
            context.registerShutdownHook();

Open in new window

As for explaining why you still see running threads, to say definitively I would need to see the spring config for your "yatraExecutorService" bean, but likely it is configured in a fairly normal way. So what you have, as the name suggests, is a Thread pool and so the Threads aren't created/destroyed when the tasks start/finish, the are kept around to possibly run further tasks if they were to be submitted.

But maybe you understand the above but were just wondering specifically why they say "Running"? This is more a status as far as the debugger is concerned, ie. they are running not "Suspended" at a breakpoint, etc. Even though the threads are listed with "Running" status they are probably not actually executing any useful code. They are probably sitting in a blocking call on a method like .take() on a BlockingQueue and so they are just waiting for a new task to be submitted to the TaskExecutor's internal queue. I hope that makes things clearer!
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
CEHJCommented:
The main problem is that the app is not exiting. The 'interest problem' is that threads are 'running' but not engaged in work tasks. Both problems are created by not shutting down the thread pool executor.
0
 
ValeriCommented:
>> The 'interest problem' is that threads are 'running' but not engaged in work tasks.
You cannot be sure about that "not engaged in work tasks". There could be a deadlock between threads, or if the search is performed in DB, if there is some problem with connections that will keep threads running.
but most probably you are right - the author has not "shutdown()" the pool. Only he knows that :-) Hey Robinsuri, put this lines:
for (;;) {
            int count = yatraExecutorService.getActiveCount();
            System.out.println("Active Threads : " + count);
            try {
                  Thread.sleep(1000);
            } catch (InterruptedException e) {
                  e.printStackTrace();
            }
            if (count == 0) {
                  yatraExecutorService.shutdown();
                  break;
            }
      }
after this lines:
for (ExtremeSearchParam param : params) {
                  SearchTask task = new SearchTask(this,param,parentFolder,countDownLatch);
                  yatraExecutorService.submit(task);      
            }

just to check if this is the case?!
0
 
CEHJCommented:
You cannot be sure about that "not engaged in work tasks".
I'm going by what Robinsuri says. Deadlock is possible but unlikely - that would be the sign of a 'broken' thread pool
0
 
CEHJCommented:
:)
0
All Courses

From novice to tech pro — start learning today.