Solved

Threads scheduled with ThreadPoolTaskExecutor keep on running

Posted on 2014-02-06
7
1,803 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 36

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
Monthly Recap

May was a big month for new releases from Linux Academy! Take a look at what our team built recently in our blog. You can access the newest releases from our blog.

 
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

Transaction Monitoring Vs. Real User Monitoring

Synthetic Transaction Monitoring Vs. Real User Monitoring: When To Use Each Approach? In this article, we will discuss two major monitoring approaches: Synthetic Transaction and Real User Monitoring.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Displaying an arrayList in a listView using the default adapter is rarely the best solution. To get full control of your display data, and to be able to refresh it after editing, requires the use of a custom adapter.
Entering a date in Microsoft Access can be tricky. A typo can cause month and day to be shuffled, entering the day only causes an error, as does entering, say, day 31 in June. This article shows how an inputmask supported by code can help the user a…
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.
Six Sigma Control Plans

687 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