Solved

Threads scheduled with ThreadPoolTaskExecutor keep on running

Posted on 2014-02-06
7
1,647 Views
Last Modified: 2014-02-10
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
0
Comment
Question by:Rohit Bajaj
  • 4
  • 2
7 Comments
 
LVL 86

Accepted Solution

by:
CEHJ earned 400 total points
ID: 39838600
Do you shut down the ThreadPoolTaskExecutor? If you don't, it's mostly likely to have runnable threads
0
 
LVL 16

Expert Comment

by:Valeri
ID: 39838676
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
 
LVL 35

Assisted Solution

by:mccarl
mccarl earned 100 total points
ID: 39838697
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
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 86

Expert Comment

by:CEHJ
ID: 39838710
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
 
LVL 16

Expert Comment

by:Valeri
ID: 39838899
>> 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
 
LVL 86

Expert Comment

by:CEHJ
ID: 39839039
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
 
LVL 86

Expert Comment

by:CEHJ
ID: 39846871
:)
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
This is an explanation of a simple data model to help parse a JSON feed
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now