Jay Roy
asked on
Executor service times out
hi guys
This below logic works fine
when i tweak the above code and wrap it with runnable it doesnt work
Although there are no compilation errors, the above code when invoked times out.
Any idea why?
thanks
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(..){
}
}
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);
}
Although there are no compilation errors, the above code when invoked times out.
Any idea why?
thanks
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.
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
ASKER
do i explicitly need to shutDown()..doesnt this happen automatically?
afaik it doesn't
ASKER
any idea what the solution should be?
I am doing
...
executor.submit(expTask);
executor.shutdown();
but i see the same problem.
I am doing
...
executor.submit(expTask);
executor.shutdown();
but i see the same problem.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
>> Just follow the example in the javadoc
which example are you talking about exactly?
Is it This one ?
If yes,. how do i incorporate it in my code?
thanks
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();
}
}
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);
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
ASKER
sorry, i think i wasnt clear. what i meant was
what does this method shutdownAndAwaitTerminatio n() 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 shutdownAndAwaitTerminatio n(Executor Service 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().int errupt();- -what does this do?
}
}
what does this method shutdownAndAwaitTerminatio
I am trying to understand step by step (my comments in italics)
executor.submit(expTask); --> i am submitting task to executor
void shutdownAndAwaitTerminatio
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
pool.shutdownNow(); // Cancel currently executing tasks
if (!pool.awaitTermination(60
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
Thread.currentThread().int
}
}
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?)
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?)
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 shutdownAndAwaitTerminatio n() 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.newFixedThreadPo ol(3);
and that is why i am seeing a performance improvement ?
thanks
yes BUT i am seeing a performance improvement when i am using the ExecutorService code.
and when i use shutdownAndAwaitTerminatio
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.newFixedThreadPo
and that is why i am seeing a performance improvement ?
thanks
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 :)
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...
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.
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()
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?
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?
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.
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.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
What do you mean by that? Also please post all code where the ExecutorService is use