I am using a thread pool for my task. After completion of each task I am destroying the thread using Thread.stop() and Thread.destroy(). But after running my application (in Eclipse) for around 30 min. I am getting a Memory out of bound error.
Please suggest me how to kill the thread.
If you're using a thread pool, you shouldn't be terminating the thread to start with - the whole point of a thread pool is to reuse threads.
If you don't want to reuse the thread, then just start a new thread instead of using a thread pool - and just let the thread die, instead of calling stop or destroy. These methods are deprecated for good reason - they basically shouldn't be called.
It's not really clear how this would cause an out of memory exception though - is there any reason why you're focusing on threading as the probable cause?
To reinforce what #Jon Skeet said, it is a REALLY BAD IDEA to call the deprecated Thread.stop() or Thread.destroy() methods.
According to the javadoc, Thread.destroy() was fundamentally dangerous and was never implemented. The original idea was simply to kill the thread and break all of its monitor locks. If it happened to be in the middle of updating a shared data structure, the data structure would be left in an indeterminate state. Other threads waiting for the killed thread to notify some object would wait for ever.
Thread.stop() causes a ThreadDeath exception to be raised at an unexpected (to the code that was hit) place. It is a little bit more orderly than killing a thread, but unless all of the stopped thread (including anything that it calls) is carefully written with finally blocks to notify waiters, restore data structures, etc, you have the same problem.
Refer to Java Thread Primitive Deprecation for the whole story.
When the task is complete, the thread run should return. Do nothing more. That will take care of things.
In debug mode the threads are not cleared by the garbage collector.
Try to run the app instead of run in debug mode and everything should be fine.
Related
I saw some posts on stackoverflow and read through the tutorials that oracle posted on destroying threads. From what I understand, once you start() a thread, you cannot use stop() to remove that thread. Instead of actually removing the thread from the scheduler, it is recommended to make the thread sleep() indefinitely. Is this thinking right?
Also this brings me to my next question, is this why people use thread pools?. Instead of "sleeping" a thread, it is more resourceful to use that thread to work on other jobs rather than creating new threads. Please let me know if my understanding of multi-thread management is right. It doesn't make sense that Java doesn't allow for a thread to be completely removed in a safe manner.
It is generally considered a very bad idea to forcibly stop a thread once it has started (or to make it sleep indefinitely) because the thread will not be able to clean up any of the resources it has acquired. For example, if a thread acquired a lock and is forcibly killed or slept indefinitely, then the lock will not be released and deadlock can ensue. Similarly, if the thread was making changes to a data structure and killed early, the data structure might be in a corrupted state, causing serious problems later on.
The best way to stop a thread in Java is to interrupt the thread and tell it that it needs to try to shut down as soon as possible. That way, the thread can try to stop what it's doing and release any resources before shutting down. In other words, you request that the thread shut down, rather than forcibly killing it.
This is not related to why thread pools exist. Thread pools are useful because there is usually some overhead associated with creating or destroying threads, due to the internal JVM or OS-level bookkeeping required to track the thread's state and progress. Thread pools make it possible to recycle threads and have them perform different tasks by having the threads sleep until a task is ready, then wake up and perform the task. This can be much faster than spawning off a new thread, performing the task yourself, then tearing down the thread.
Hope this helps!
As templatetypedef mentioned, you shouldn't be forcibly stopping a thread, you should signal to a thread to stop. For example, whenever your thread is blocking, it should be done in a while loop that tests the condition it is blocking on, as well as the condition to quit:
while (!condition && !stop) {
try {
someBlockingFunction(); // A lock, take on a BlockingQueue, etc.
} catch (InterruptedException e) { //ignored }
}
Upon exiting the while loop, check to see if we have been signaled to stop (stop = true) by another thread, if so return from the run() function to allow the thread to clean itself up.
I am in a wierd situation. In my web-server (tomcat), on web request, I basically need to cancel a previous request. I have a reference to the thread that was executing the previous request. So I can directly interrupt that thread and the node will do the rest.
I know you are not suppose to interrupt the thread which you do not own. But is it safe to interrupt tomcat thread in this case? What can be the other way? Maintaining own thread pool is waste of resources and ovehead
Maintaining your own thread pool is a waste of resource but it's also a gain in every other respect, like stability of your application server. So you need to decide what is more important: A few thousand bytes of memory and CPU cycles or a stable, reliable application.
The problem with interrupting another thread is that you usually can't know for sure where in the code that other thread is. You might want to use locking for this:
Thread A locks something while it's safe to interrupt, thread B checks the lock and if it can't get it, it interrupts A.
But what happens when A is just about to give up the lock, B checks the lock, A unlocks and starts with cleanup, B sends interrupt?
So you should really use your own thread pool.
I would not do it. Not 100% sure why, but I think those threads come from Tomcat's own worker thread pool and killing them one-by-one would/could eventually result in a non-responding Tomcat instance. (This is just a hypothesis).
I would argue that "maintaining own threadpool is waste of resources and overhead". I think it is a minor thing, threadpools are great guys, do no be afraid of them. I do not know the details of your application but I think if you measured the overhead by JConsole you could decide the point to do some optimization and it is not probable that the threadpool would be the bottleneck.
The best think I could suggest to you is a complete redesign: use short-returning HTTP requests to start long-running asynchronous operations in the background by submitting tasks to an ExecutorService or stuff. This way there is no need to harm Tomcat's own threads and the overall usability of your application could also be improved from a user/client perspective.
To sum up: I think it is not safe to do what you mentioned and one possible other way to do what you want is described in the above paragraph.
I am working on a multithreaded game in java. I have several worker threads that fetch modules from a central thread manager, which then executes it on its own. Now I would like to be able to pause such a thread if it temporarily has nothing to execute. I have tried calling the wait() method on it from the thread manager, but that only resulted in it ignoring the notify() call that followed it.
I googled a bit on it too, only finding that most sites refer to functions like suspend(), pause(), etc, which are now marked a deprecated on the java documentation pages.
So in general, what is the way to pause or continue a thread on demand?
You can use an if block in the thread with a sentinal variable that is set to false if you want to halt the thread's action. This works best if the thread is performing loops.
Maybe I'm missing the point, but if they have nothing to do, why not just let them die? Then spawn a new thread when you have work for one to do again.
It sounds to me like you're trying to have the conversation both ways. In my (humble) opinion, you should either have the worker threads responsible for asking the central thread manager for work (or 'modules'), or you should have the central thread manager responsible for doling out work and kicking off the worker threads.
What it sounds like is that most of the time the worker threads are responsible for asking for work. Then, sometimes, the responsibility flips round to the thread manager to tell the workers not to ask for a while. I think the system will stay simpler if this responsibility stays on only one side.
So, given this, and with my limited knowledge of what you're developing, I would suggest either:
Have the thread manager kick of worker threads when there's stuff to do and keep track of their progress, letting them die when they're done and only creating new ones when there's new stuff to do. Or
Have a set number of always existing worker threads that poll the thread manager for work and (if there isn't any) sleep for a period of time using Thread.sleep() before trying again. This seems pretty wasteful to me so I would lean towards option 1 unless you've a good reason not to?
In the grand tradition of not answering your question, and suggest that You Are Doing It Wrong, I Offer this :-)
Maybe you should refactor your code to use a ExecutorService, its a rather good design.
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html
There are many ways to do this, but in the commonest (IMO), the worker thread calls wait() on the work queue, while the work generator should call notify(). This causes the worker thread to stop, without the thread manager doing anything. See e.g. this article on thread pools and work queues.
use a blocking queue to fetch those modules using take()
or poll(time,unit) for a timed out wait so you can cleanly shutdown
these will block the current thread until a module is available
What should be done with a Thread after its run() method finishes executing? Is there any cleanup needed for a Thread in Java?
Unless the thread's work has used some unmanaged resources (network streams, files etc) - in which case it should clean up after itself - there's nothing you need to do.
Note that holding a reference to the Thread object representing the thread won't keep the underlying OS thread alive.
You don't need to, thread exits , once run method finishes it's execution
Generally cleaning up is done by the garbage collector. If the threads uses files/sockets you may need to close them. The best practice is to close resources in the top-level finally block in Thread::run.
Actually, you need to clean up your data, and not the thread.
Nopes. The thread would execute and die on its own and get garbage collected.
No its not necessary. When the thread exit its run method, the thread come into exit state itself.
I'm using a java.util.concurrent.ExecutorService that I obtained by calling Executors.newSingleThreadExecutor(). This ExecutorService can sometimes stop processing tasks, even though it has not been shutdown and continues to accept new tasks without throwing exceptions. Eventually, it builds up enough of a queue that my app shuts down with OutOfMemoryError exceptions.
The documentation seem to indicate that this single thread executor should survive task processing errors by firing up a new worker thread if necessary to replace one that has died. Am I missing something?
It sounds like you have two different issues:
1) You're over-feeding the work queue. You can't just keep stuffing new tasks into the queue, with no regard for the consumption rate of the task executors. You need to figure out some logic for knowing when you to block new additions to the work queue.
2) Any uncaught exception in a task's thread can completely kill the thread. When that happens, the ExecutorService spins up a new thread to replace it. But that doesn't mean you can ignore whatever problem is causing the thread to die in the first place! Find those uncaught exceptions and catch them!
This is just a hunch (cuz there's not enough info in your post to know otherwise), but I don't think your problem is that the task executor stops processing tasks. My guess is that it just doesn't process tasks as fast as you're creating them. (And the fact that your tasks sometimes die prematurely is probably orthogonal to the problem.)
At least, that's been my experience working with thread pools and task executors.
Okay, here's another possibility that sounds feasible based on your comment (that everything will run smoothly for hours until suddenly coming to a crashing halt)...
You might have a rare deadlock between your task threads. Most of the time, you get lucky, and the deadlock doesn't manifest itself. But occasionally, two or more of your task threads get into a state where they're waiting for the release of a lock held by the other thread. At that point, no more task processing can take place, and your work queue will pile up until you get the OutOfMemoryError.
Here's how I'd diagnose that problem:
Eliminate ALL shared state between your task threads. At first, this might require each task thread making a defensive copy of all shared data structures it requires. Once you've done that, it should be completely impossible to experience a deadlock.
At this point, gradually reintroduced the shared data structures, one at a time (with appropriate synchronization). Re-run your application after each tiny modification to test for the deadlock. When you get that crashing situation again, take a close look at the access patterns for the shared resource and determine whether you really need to share it.
As for me, whenever I write code that processes parallel tasks with thread pools and executors, I always try to eliminate ALL shared state between those tasks. As far as the application is concerned, they may as well be completely autonomous applications. Hunting down deadlocks is a drag, and in my experience, the best way to eliminate deadlocks is for each thread to have its own local state rather than sharing any state with other task threads.
Good luck!
My guess would be that your tasks are blocking indefinitely, rather than dying. Do you have evidence, such as a log statement at the end of your task, suggest that your tasks are successfully completing?
This could be a deadlock, or an interaction with some external process that is blocking.
Although you don't leave enough detail to be sure, the first thing I'd try is to have your tasks catch "Exception" at the top level and log the message.
I know it doesn't seem right, but occasionally (depending on a lot of variables) I've worked on code where stuff happening in a thread throws an exception and it is never logged, or it just doesn't show up on the console--yet the "executing" code exits out of it's top level loop or whatever code is causing your task to run.
I guess I'm just saying, make sure your tasks are not throwing an exception out.