Solved

Executor service times out

Posted on 2012-03-14
21
237 Views
Last Modified: 2012-03-24
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
0
Comment
Question by:royjayd
  • 10
  • 6
  • 5
21 Comments
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
times out

What do you mean by that? Also please post all code where the ExecutorService is use
0
 

Author Comment

by:royjayd
Comment Utility
>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.
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
In that case you're not closing down the ExecutorService properly. See the javadoc example
0
 

Author Comment

by:royjayd
Comment Utility
do i explicitly need to shutDown()..doesnt this happen automatically?
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
afaik it doesn't
0
 

Author Comment

by:royjayd
Comment Utility
any idea what the solution should be?

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

but i see the same problem.
0
 
LVL 86

Accepted Solution

by:
CEHJ earned 250 total points
Comment Utility
It's not just shutdown you need. You need to call awaitTermination too. Just follow the example in the javadoc
0
 

Author Comment

by:royjayd
Comment Utility
>> 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
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
Yes. Just paste it into your class and do

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

Open in new window

0
 

Author Comment

by:royjayd
Comment Utility
OK. Can you tell me why I. Need to call that method?
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
You don't need to call that method, just the right methods of ExecutorService
0
 

Author Comment

by:royjayd
Comment Utility
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?
   }
 }
0
 
LVL 35

Expert Comment

by:mccarl
Comment Utility
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?)
0
 

Author Comment

by:royjayd
Comment Utility
>>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
0
 

Author Comment

by:royjayd
Comment Utility
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 :)
0
 
LVL 35

Expert Comment

by:mccarl
Comment Utility
> 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.
0
 
LVL 35

Expert Comment

by:mccarl
Comment Utility
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?
0
 

Author Comment

by:royjayd
Comment Utility
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.
0
 
LVL 35

Expert Comment

by:mccarl
Comment Utility
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.
0
 

Author Comment

by:royjayd
Comment Utility
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.
0
 
LVL 35

Assisted Solution

by:mccarl
mccarl earned 250 total points
Comment Utility
Definitely go without it, for the following reasons...

it will actually be (very slightly) degrading performance due to overhead of creating an unnecessary thread for each request
it will be using extra resources as the extra thread per request takes memory to manage
it makes it harder to read the code, harder to maintain the code at a later date when you or someone else comes back to it and wonders what it is doing
(and I'm sure a few more)


Is the concurrency of multiple threads handled by application servers?
Yes, I'm not experienced in WebLogic specifically, but all app servers would be able to serve requests in a multi-threaded way (or at least have options to enable this) and they would have settings pertaining to the thread pool that is used to serve the incoming requests!
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
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.

771 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

10 Experts available now in Live!

Get 1:1 Help Now