aspose file tools*
The moose likes Threads and Synchronization and the fly likes use thread to stop application hanging Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "use thread to stop application hanging" Watch "use thread to stop application hanging" New topic
Author

use thread to stop application hanging

steve Barf
Greenhorn

Joined: Oct 15, 2004
Posts: 26
Would the use of a thread be a way to run a piece of code seperately without causing an application to hang ?

The problem I have is that this bit of code :

SmtpClient client = new SmtpClient(SMTP_SERVER_IP);

sometimes hangs causing the whole application to hang, if I could put it in a seperate method or thread that timesout then I could retry it if the first attempt hangs.

Note that I am very worried about using threads because the application had a problem of one user setting up data for another user due to the jsp's/servlets not being synchronised - so I went thru and synchronised them all.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Servlets are designed so that many threads can execute on the same object instance at the same time. I'd guess where you got into trouble before was using member variables or static variables for things that related to one user request. When multiple threads come through you might set and read a variable and find that another thread changed it in between. Synchronizing the works of your servlets might solve the problem, but it forces your server to only work for one user at a time and will have huge impact on your ability to handle lots of users at once. I'd try to get away from that synchronized solution right away.

One way is to move all your methods out of the servlet into a command or worker class.

Now you get a new worker object for every thread and they don't have to worry about one thread clobbering data from another thread.

Re the other thing you asked - spinning off a new thread to do some communication - where is this happening? In a servlet container? EJB container?


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
steve Barf
Greenhorn

Joined: Oct 15, 2004
Posts: 26
Hi Stan,
Thanks for your detailed reply. Your first assumption that variables were being overwritten is right, even this took a while to work out as I am such a greenhorn. Because this was a live application I needed a fix urgently otherwise we would have to shut the application down - putting SYNCHRONIESED at the start of each servlet doPost method and isThreadSafe='false' at the start of each JSP was a miracle cure. The application is fairly low usage so response times were not an issue.

Your description of a worker class seems so obvious now - is this the recommended method ? Is there a simple book/website you could recommend ?
I would be interested in using this approach but converting the existing application would be a big job.

But this is the real reason for my post.
The code I wanted to isolate is currently in a java bean (not EJB) called from a servlet. Intermittently it seems to hang on the statement :

SmtpClient client = new SmtpClient(SMTP_SERVER_IP);

the server CPU goes up to 100% and the web server cannot process any more requests. If I could run this code and get it to timeout in some way then I could retry it several times until the client was created.
Steve
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

I put all network communications in a seperate thread. (are you listening microsoft!?)

I NEVER allow the whole applicaiton to lock up. I always allow the user the cancel an action no matter what it is. Sometimes actions are not cancelable for some reason, but that is very very rare.

Yes, please use a seperate thread when waiting on data coming across the network.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Another vote for keeping external communications in their own threads or having a good timeout strategy. It can be challenging to rejoin a separate thread to present results. CL, do you do that in server apps or fat-client apps? Any tips?

I'm surprised your CPU goes to 100%. Usually when I'm blocking on waiting for a response it tends more toward 0% than 100%.

The worker class thingie is common. Struts and other "front controller" designs use em. I haven't used Struts myself - can anybody say if it creates a new command or task or whatever? Or does it use singletons?

The servlet spec uses singletons for a reason, tho. It cuts down on object creation and garbage collection and may perform a bit better. When you create new work classes every time, you counter-act whatever advantage the servlet engine got from singletons. That's not a life-threatening problem, just something to be aware of.

Finally, the other approach that I forgot to mention is to simply not use any member variables. If you can keep everything in local variables inside various methods while you process the request you're thread safe again.
steve Barf
Greenhorn

Joined: Oct 15, 2004
Posts: 26
Stan/CL,
Thanks for your thoughts above, can you give me more of an idea how I can run this bit of code :

SmtpClient client = new SmtpClient(SMTP_SERVER_IP);

and check whether it has completed or not, allowing for the fact that it may not complete and so may need to be cancelled or abandoned somehow.

Steve
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Oh, it just dawned on me, it's your synchronized methods that cause the whole thing to hang. No other requests can get into the servlet until the slow one is done. You might have a deadlock somewhere if that SMTP thing never comes back. I think synchronized put you in a bad place. Even if you spawn another thread, you'll have to exit the servlet methods to let another request into the servlet. Then you've got the IO thread running and the user sitting there looking at, um, Idunno what. Sometime later the IO thread ends and it's not at all easy to let the user know.

Anybody know a way to get Steve out of this?
steve Barf
Greenhorn

Joined: Oct 15, 2004
Posts: 26
Stan,
Had any suggestions yet ?
Steve
Warren Dew
blacksmith
Ranch Hand

Joined: Mar 04, 2004
Posts: 1332
    
    2
Seems like the right thing to do is fix it the right way: remove dependencies on static variables or data members of the servlet.

Normally you shouldn't end up with any servlet member variables anyway when using JSP pages; variables in the JSP pages are converted to local variables in the corresponding servlet's service() method.

You can get into trouble if you insert any classes into the inheritance hierarchy between the JSP page and the normal servlet class, because any members of such a class then are shared between all executions of the page. The best thing to do in this case is to redesign so that you don't have such inserted classes, perhaps creating instances in the pages instead; the next best thing is to store any members of such inserted classes into ThreadLocal objects so there will be one per user thread.
[ November 05, 2004: Message edited by: Warren Dew ]
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by steve Barf:
...

SmtpClient client = new SmtpClient(SMTP_SERVER_IP);

the server CPU goes up to 100% and the web server cannot process any more requests. If I could run this code and get it to timeout in some way then I could retry it several times until the client was created.
Steve


Is this piece of code located in the server or the client? I would use a debugger and check what this method is doing. But in any evnt I am also of the mind that pegged at 100% is a bug. looks more like racing instead of deadlock. When its pegged can you get a thread dump? Which JVM are you using?
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Stan James:
Another vote for keeping external communications in their own threads or having a good timeout strategy. It can be challenging to rejoin a separate thread to present results. CL, do you do that in server apps or fat-client apps? Any tips?...


I do this in _all_ my apps. stalled aps are never good. So i have use it in thin clients, and 'fat' clients, and servers. But on the servers its usually just a timeout. My servers can be rude But the clients I want to give the user the ability to cancel so its mostly a UI thing, but also can help integrity. I like the user to know whats happening and be able to control it.
steve Barf
Greenhorn

Joined: Oct 15, 2004
Posts: 26
Thanks for your replies, sorry for no getting back to you sooner.

Warren, yes I won't use static variables again, but I'm not confident enough to convert this existing application.
Would there be a way to use ThreadLocal objects as you suggested even though the servlet is synchronised and run the offending code in this?
If so I'd be grateful if you could explain how this works possibly with a code example,
remebering the problem I get is that the code hangs,
if so would the thread hang and if so could I detect this and repeat the operation till it completes ?

CL, could you explain the 'good timeout strategy' you mentioned, your sentence
"Another vote for keeping external communications in their own threads or having a good timeout strategy."
implies that seperate threads would not be required for this.

Thanks Steve
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Timers almost always have seperate threads too, so I didn't mean to imply that. There is no way around havin more threads here. I have not written a single program with network connectivity without having multiple threads. Timers are just a different way of accomplishing the same thing, tough I think its the less smooth of the two choices.
steve Barf
Greenhorn

Joined: Oct 15, 2004
Posts: 26
CL
Can I have a seperate thread even though the servlet is synchronised or is that nonsense? If you could give me an example of how you use a timer I would be very grateful.
Steve
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

You can have as many threads as you like. What you do is make sure the call that is going to block is inside of a different thread, so your whole program does not block. This has to make sense for your program though.

Its definitely hard to explain. I have code you can look at on my website though. I learned some of my techniques by examiing other code, so it couldnt hurt for you to do the same.



First the idea of retrying this if the first attempt hangs is improper unless you can cancel it. If it hangs then there is a problem and you need to deal with it before you try again.

What does the constructor do? What part of it can hang? Why can it hang? Can you interrupt it if its hung? Your really not supposed to do much at all in constructors so I am surprised the constructor itself is hanging.

Anyway, what is the rest of your program going to be doing while its waiting on the constructor to return?
steve Barf
Greenhorn

Joined: Oct 15, 2004
Posts: 26
CL,
I think the problem is a network problem (the SMTP server chap started talking about reverse pings ..),
on odd occasions the smtpclient isn't created properly, and this is what I was trying to handle.

Looking back at your first reply you seem to have separate threads for IO probably for this reason.

I would appreciate being able to see a code example from your website, if it's not too complicated
and if you could direct me to a suitable piece of code I'd be grateful.

I was wondering if the application could have 3 goes at creating the smtpclient, and putting a time limit
of say 2 seconds on each attempt to create the client.

In pseudo-code I was thinking of something like :


clientcreated=false;

loop (3 times while clientcreated=false)

create thread

loop (for 2 seconds while clientcreated=false)
end loop

if (clientcreated=false)
cancel thread

end loop

if (clientcreated=false)
error

thread
{
create smtpclient
clientcreated=true
}


Remembering that the rest of the application is synchronised, this shouldn't hold up other users
except when there is this intermittent problem, and then only for 6 seconds.

But again it may not make sense to have a thread in a synchronised application.
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

my website is rigidsoftware.com. The chess program source is available. I would suggest looking at the classes

IOProcessor and MainFrame I guess

though in looking myself I find it hard to see wth i was doing

I looks like IOProcessor has a run method like so



and there are connect and disconnect methods


main application creates and starts the iop thread. then calls Login to login or Exit to exit, both of these method return immediately as you can see and do not block the GUI. Then the GUi has a listener registered on the communication class, and once it is connected it lets the GUI know, or something like that. Probably the GUI has a timer that checks every second to see if its connected. I hope you get the idea. code was complicated for me to understand. that was before I found Eclipse and stuff and was done by Visual Cafe which was sorta nasty
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

steve, dont loop, create a timer and register a listener with it should call some method when its time to disconnect the failed attempt.

but be careful about the GUI thread that you dont violate it.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: use thread to stop application hanging