Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 291
  • Last Modified:

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
0
royjayd
Asked:
royjayd
  • 10
  • 6
  • 5
2 Solutions
 
CEHJCommented:
times out

What do you mean by that? Also please post all code where the ExecutorService is use
0
 
royjaydAuthor Commented:
>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
 
CEHJCommented:
In that case you're not closing down the ExecutorService properly. See the javadoc example
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
royjaydAuthor Commented:
do i explicitly need to shutDown()..doesnt this happen automatically?
0
 
CEHJCommented:
afaik it doesn't
0
 
royjaydAuthor Commented:
any idea what the solution should be?

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

but i see the same problem.
0
 
CEHJCommented:
It's not just shutdown you need. You need to call awaitTermination too. Just follow the example in the javadoc
0
 
royjaydAuthor Commented:
>> 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
 
CEHJCommented:
Yes. Just paste it into your class and do

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

Open in new window

0
 
royjaydAuthor Commented:
OK. Can you tell me why I. Need to call that method?
0
 
CEHJCommented:
You don't need to call that method, just the right methods of ExecutorService
0
 
royjaydAuthor Commented:
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
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
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
 
royjaydAuthor Commented:
>>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
 
royjaydAuthor Commented:
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
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
> 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
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
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
 
royjaydAuthor Commented:
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
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
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
 
royjaydAuthor Commented:
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
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
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

[Webinar On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 10
  • 6
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now