Link to home
Start Free TrialLog in
Avatar of Jay Roy
Jay RoyFlag for United States of America

asked on

Executor service times out

hi guys

This below logic works fine

public class ExcelView extends AbstractExcelView  {

protected void buildExcelDocument(Map map, HSSFWorkbook wb,HttpServletRequest request, HttpServletResponse response)throws Exception
{
 getExportDocumentObject(true, "Excel",buffer, mReq,wb); 
}

public DocumentObject getExportDocumentObject(...) {
try {
getTitleRow(..);	
getDataRows(..);
} catch (Exception e) {
	}
return documentObject;
}

private void getTitleRows(..){
}

private void getDataRows(..){
}

}

Open in new window


when i tweak the above code and wrap it with runnable it doesnt work


public class ExcelView extends AbstractExcelView  {

protected void buildExcelDocument(Map map, HSSFWorkbook wb,HttpServletRequest request, HttpServletResponse response)throws Exception
{
 ExecutorService executor = Executors.newFixedThreadPool(3);                        
 final HSSFWorkbook runnableWb = wb;
 Runnable expTask = new Runnable(){  	
 public void run(){        
 getExportDocumentObject(true, "Excel",buffer, mReq,runnableWb); 
 } //close run()

public DocumentObject getExportDocumentObject(..) {
try {
getTitleRow(..);	
getDataRows(..);
} catch (Exception e) {
}
return documentObject;
}

private void getTitleRows(..){
..
}

private void getDataRows(..){
..
}
 };// close runnable  
executor.submit(expTask);
}

Open in new window


Although there are no compilation errors, the above code when invoked times out.
Any idea why?


thanks
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

times out

What do you mean by that? Also please post all code where the ExecutorService is use
Avatar of Jay Roy

ASKER

>What do you mean by that?
The code creates an excel sheet and populates it with data using HSSFWorkbook POI api . If i dont use ExecutorService it works fine(the first code section above).

In the second code section..When i use ExecutorService it does not throw any error on console but it takes a long time to finish and finally i get a blank excel sheet on the screen (without any data) and a popup box which says "There was a problem sending the command to the program".

>>Also please post all code where the ExecutorService is use
Like posted above, ExecutorService it used only at one single place.
I am just wrapping the code within run() and finally doing
executor.submit(expTask);

thx.
In that case you're not closing down the ExecutorService properly. See the javadoc example
Avatar of Jay Roy

ASKER

do i explicitly need to shutDown()..doesnt this happen automatically?
afaik it doesn't
Avatar of Jay Roy

ASKER

any idea what the solution should be?

I am doing
...
executor.submit(expTask);
executor.shutdown();

but i see the same problem.
ASKER CERTIFIED SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Jay Roy

ASKER

>> Just follow the example in the javadoc
which example are you talking about exactly?

Is it This one ?

 void shutdownAndAwaitTermination(ExecutorService pool) {
   pool.shutdown(); // Disable new tasks from being submitted
   try {
     // Wait a while for existing tasks to terminate
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     pool.shutdownNow();
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }
 }

Open in new window



If yes,. how do i incorporate it in my code?

thanks
Yes. Just paste it into your class and do

executor.submit(expTask);
shutdownAndAwaitTermination(executor);

Open in new window

Avatar of Jay Roy

ASKER

OK. Can you tell me why I. Need to call that method?
You don't need to call that method, just the right methods of ExecutorService
Avatar of Jay Roy

ASKER

sorry, i think i wasnt clear. what i meant was
what does this method shutdownAndAwaitTermination() from java docs do
I am trying to understand step by step (my comments in italics)

executor.submit(expTask); --> i am submitting task to executor
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown();//once the above task has been executed by threads,shut down executor  
 try {
     // Wait 60 seconds  for existing tasks to terminate
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) { //if task doesnt finish in 60 sec you forcibly shutdown      
pool.shutdownNow(); // Cancel currently executing tasks
       
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))--what does this do?
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     pool.shutdownNow();
     Thread.currentThread().interrupt();--what does this do?
   }
 }
What are you trying to achieve by executing this code via the Executor service?

After the other question that I have been helping you with, can I assume that you were hoping that it would make the getExportDocument code run in 3 threads in parallel? That won't happen.

The reason that you are seeing a problem here is basically, because when you submit the task, you will now have 2 threads, the one that was running the buildExcelDocument method and a new one to execute your Runnable's run method. The first thread continues to run any code after the submit call, which there is NONE and so it returns immediately. Now, the whole idea behind AbstractExcelView is that it expects that the document has been created and is ready to go when the buildExcelDocument method finishes, but now in your case, your other thread is still busy building the document, while AbstractExcelView is trying to send it back to the client.

So essentially, you can't do what it looks like you are trying to do, at least not like this. So to re-iterate, what is you aim for trying to do this? (Does it take a long time for the code to build this document? Or is it something else?)
Avatar of Jay Roy

ASKER

>>Does it take a long time for the code to build this document?

yes BUT i am seeing a performance improvement when i am using the ExecutorService code.
and when i use shutdownAndAwaitTermination() methods it does solve the original problem(my first post). So now there is no delay and it executes pretty fast.

One thing which i wanted to clarify on what you said
>>>The first thread continues to run any code after the submit call, which there is NONE and so it returns immediately.
Totally Agree, so now the runnable task will be distributed among three threads
>>ExecutorService executor = Executors.newFixedThreadPool(3);                        
and that is why i am seeing a performance improvement ?

thanks
Avatar of Jay Roy

ASKER

ok i am reading the other posts and i see you mention only one thread process the task.
Now i am confused why there is a performance improvement :)
> BUT i am seeing a performance improvement when i am using the ExecutorService code

Are you sure that this isn't due to some other influence, because there is no logical explanation for the code to affect this. Are you sure that you are doing a like for like comparison, ie. building the exact same document, and that there are no caching influences happening when testing the old code and the ExecutorService code? See below for the reason..

> so now the runnable task will be distributed among three threads

No, I will say again (see your other question), for one request for an Excel document there will be one invocation of the buildExcelDocument method, one Runnable task submitted to the executor, and so the code within the run() method will execute on ONE thread. There is no magic multithreading going on here; us programmers would probably be paid much less if multithreading a section of code was this easy!!

Try something, to show yourself what is happening, in the code for the ExecutorService, change it to look like this...

ExecutorService executor = Executors.newFixedThreadPool(3);                        
final ThreadPoolExecutor tpe = (ThreadPoolExecutor) executor;
 final HSSFWorkbook runnableWb = wb;
 Runnable expTask = new Runnable(){  	
 public void run(){        
 getExportDocumentObject(true, "Excel",buffer, mReq,runnableWb); 
 System.out.println("Pool size: " + tpe.getPoolSize());
 } //close run()

Open in new window


Note: the lines that have been added are line 2 and line 7. Just add those lines to the corresponding places in the code that you currently have. (I don't think this part would have changed much)

Then make a request for an excel document. You should see "Pool size: 1" in the stdout console of your app server. This shows that only 1 thread was started. If you make another request, then is will print "Pool size: 2", and so on but will never go over 3, as that is the size of the pool.
Most of the above was typed before you made the comment, so I see now that you have read my other posts.

To test the performance, I would first use the new ExecutorService code, and make a number of requests for a particular excel document (the same each time, this will make sure there you don't get messed up with caching issues), and measure the time it takes.

Now, change back to the old non-ExecutorService code, and do the same. Make sure that it is requesting/building the exact same excel document, and again, do it a number of times.

See how they compare now?
Avatar of Jay Roy

ASKER

After running multiple test cases we figured there wasnt really any performance improvement. so in a single threaded environment is there a way to improve the performance for my application.
What we really need to know, is what does that getExportDocumentObject(...) method do, and how does it do it? ie. Is there a lot of calculations? Or is there database accesses? etc. It would be that method that is taking the bulk of the time, I would guess so that is where I would look. But you should probably confirm that with some profiling. Put calls to System.nanoTime() on either side of the call to getExportDocumentObject() and calculate the time spent in that method. Thinking about it now, there could be other issues, such as the amount of time it takes to stream the document back to your client browser, or the amount of time your client browser takes to render the document, using Excel or some buitin excel renderer. The idea with optimization is to tackle the part that is taking the longest time first, as it has the greatest opportunity to make improvements.
Avatar of Jay Roy

ASKER

Alright, will take a look into the internal working of getExportDocumentObject code.

Also, Is it better to go with the ExecutorService implimentation (although it doesnt improve the performance in my case) or to go without it ?
Our application is deployed on weblogic application server and there are about 4000 users
who will access this export feature at the same time. Is the concurrency of multiple threads handled by application servers?

thx.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial