I've got a question about threads. When I do sth like this:
new Thread(new Runnable(){
#Override
public void run() {
//sth to do
}
}).start();
What happens when all the code in run() is executed ? Does the system automatically deletes the thread or does the thread still remain in memory?
thx & regards
When a thread finished its run() method, it will enter the 'dead' state. Then the next thread in your stack runs after.
Dead state :
"A thread is considered dead when its run() method completes. It may
still be a viable Thread object, but it is no longer a separate thread
of execution. Once a thread is dead, it can never be brought back to
life! (The whole "I see dead threads" thing.) If you invoke start() on
a dead Thread instance, you'll get a runtime (not compiler) exception.
And it probably doesn't take a rocket scientist to tell you that if a
thread is dead, it is no longer considered to be alive."
Java's Threading Model is a little bit more complicated than that.
Basically, a java.lang.Thread is just a wrapper around some data, not a process by itself. When you call the .start() method, a native thread is created and linked to your java Thread. This work is done by the JVM using internal data structures (JavaThread and OSThread).
Once the .run() method finish, many operations are performed by the JVM to delete the native thread that was used. Therefore, you won't see this thread anymore in you process list (using top or ps, for example).
However, the objects that were allocated in the heap and the java.lang.Thread instance itself stay in memory until a GC cycle collects them.
So, to sum up :
Yes, the JVM deletes the native thread that was used
No, the JVM does not delete the java.lang.Thread instance that was used
The GC will eventually collect this instance
For more information, you should read the book "Java Performance" by Charlie Hunt. It contains lots of information on this topic (and many others).
Hope that helps !
When the code in a thread finishes executing, the thread is stopped.
The Thread instance will still exist until it gets GC'd, but the actual system thread will no longer exist.
If you don't use any custom-configured thread pool mechanism, your thread will die and the Threadobject itself will be eligible to garbage collection.
Related
Consider this question.
Now there are various reasons as why creating a thread is expensive, notably the fact that a lot of memory needs to be allocated and the thread needs to be registered.
Now consider this code:
Thread thread = new Thread(new SomeRunnable());
thread.start();
Which part of that is the "expensive" part? The line that actually creates the Thread object or the line that starts the thread? Or both? The reason why I am asking is because I am writing the server-component of a game and I am debating if I should create the Thread object as soon as the player connects and start the thread once the player finishes logging in, or should I both create and start the thread after the player finishes logging in.
Creating a Thread object is very cheap. You just pay the price of calling the constructor. It's the start() method that takes up space (native calls, stack memory, etc.)
On the other hand if you create plenty of threads, consider creating (and starting them) in advance and having a pool. This is already done for you, check out Executors class.
This really smacks of premature optimization to me. I really doubt that you are going to see any difference between instantiating or starting the thread earlier rather than later. If it was 100 threads then I might feel differently.
If you have seen performance problems with your application then I would encourage you to use a profiler to discover the real performance sinks.
If you want to avoid the cost of thread creation, use a Thread pool. I agree with #Gray though. Like a connection pool, a thread pool keeps you from creating things over and over again (and it keeps the number of threads from growing uncontrollably).
[Before I begin I tried searching related questions, since I found none, I ask a question here]
I am learning Java, and the following scenario hit my head:
class MyThread extends Thread {
void run(){
//a heavy function
}
}
And now in the main thread, I invoke this thread as:
public static void main(...){
new MyThread().start();
System.gc(); //just a request..
//end of main thread too.
//Reference to that MyThread object is now zero.
}
I ran that code. It seems the thread is still alive. The program ends when all the threads quit.
My questions:
When the reference count is zero, wont the thread be eligible for GC? If it is really eligible, what is the behaviour of garbage collection? Will the thread be terminated?
I know its a bad thing to do but is it well defined to not have otherThread.join() in main()?
I have a few explanation of myself (but I do not know how right I am -- the reason I made a post here):
JVM maitains a reference to the thread as long as it is active. So ref count is never really zero.
The executing function has an implicit this reference, so the ref count is again not zero.
Am I correct in any of the explanations above? Or is there any other explanation altogether?
Thanks and regards :)
Each running thread constitutes a root for the GC. Any object reachable from one of the roots is not eligible for GC, and the thread has a thread-local reference to the java.lang.Thread instance (returned by Thread.currentThread()). So no, your thread won't be GCed until it ends running, since the Thread instance is reachable from the running thread.
I don't see why it would be a bad thing not to call join() on the spawned thread. If you don't care when the spawned thread ends, you don't need to join it. The application will stop when the last non-daemon thread stops running.
Also, note that the number of references is not what is used by the GC to tell if an object is eligible for GC or not. Graphs of objects which maintain references to each other (a DOM tree for example) can be eligible for GC, if the graph is not reachable anymore.
1. JVM will terminate only when all the Non-Daemon thread including the Main thread has terminated. (Main thread not the main() method).
2. A Thread will die immediately as it has finished running its run() method, But as you will be knowing that, every thread (toe, ie thread of execution) is associated with the Instance of the Thread class.
3. So when the thread die, it moves in to the dead state (i am not mentioning the thread pool here) , But the object of Thread class which was associated with the thread is still there, but has permanently lost its threadness.
4. But there is a high chance that your thread is still running only the main method has finished.
5. Calling join() is not at all bad, but should be used with caution.
When the reference count is zero, wont the thread be eligible for GC?
No. A thread becomes eligible for GC when it terminates and there are no references.
If it is really eligible, what is the behaviour of garbage collection? Will the thread be terminated?
See above.
I know its a bad thing to do but is it well defined to not have otherThread.join() in main()?
It isn't a bad thing to do, and it is perfectly well-defined: the JVM will exit when all the non-daemon threads have exited.
JVM maitains a reference to the thread as long as it is active. So ref count is never really zero.
Correct.
The executing function has an implicit this reference, so the ref count is again not zero.
Incorrect. Consider static methods. The executing function is executing in an active thread, by definition, so the thread is active, by definition, so it can't be GC'd. Your thinking here is rather circular.
is there any way to confirm if the thread is killed at the end of execution? If the garbage collector takes long time to destroy the threads even when they are available for GC, out of memory exceptions may arise. to get rid of those kind of issues, it would be good to know if the threads have been destroyed.
As of now, my understanding is that at the end of run method , the thread gets killed and we need not do anything explicitly to kill the thread instance.
Thanks in advance!
class A
{
public static void main()
{
Thread t = new Thread(new TestA());
t.start();
Thread t1 = new Thread(new TestB());
t1.start();
Thread t2 = new Thread(new TestC());
t2.start();
}
}
class TestA implements Runnable {
Thread t;
public void run() {
for(...){
try{
}catch()
{
....
}
}
}
}
You are absolutely right that "at the end of run method, the thread gets killed and we need not do anything explicitly to kill the thread instance". Simply letting the thread leave its run() method normally is enough.
If you want to make sure that a particular thread has terminated, then Thread.isAlive() will check, and Thread.join() will wait until it happens. If you have a particular set of threads that you're worried about, then keep a reference to them somewhere, and check up on them using these methods.
Thread.getAllStackTraces()
gets you a current map of threads/stacktraces. However I would normally expect the JVM to clear up the threads upon exit from run(). Obviously if you're using some sort of thread pooling then that's not the case.
You can use some softwares like visualvm to monitor the thread states .
These kind of softwares will give you full flexibility to profile your application in a visual way.
To check the state of a thread , you can call the getState() method on a thread object to see the state of the thread.
The javadoc of OutOfMemoryError says:
Thrown when the Java Virtual Machine cannot allocate an object because
it is out of memory, and no more memory could be made available by the
garbage collector.
So, if a thread is not running anymore and is eligible to GC, the GC will try to collect it before throwing an OOM. Like with any other object.
is there any way to confirm if the thread is killed at the end of execution?
There's no sense confirming something you know to be true. Whenever the JVM process dies, all its threads are automatically killed by the operating system. Any other behavior is a bug in the OS.
If the garbage collector takes long time to destroy the threads even when they are available for GC, out of memory exceptions may arise.
The garbage collector doesn't kill threads - the JVM wraps operating-system-specific thread libraries into a consistent Java-language thread abstraction, so those thread libraries determine when a thread dies.
my understanding is that at the end of run method, the thread gets killed and we need not do anything explicitly to kill the thread instance.
That is correct.
If you look up in the javadoc for the Thread class you will see many methods that might help you check what you want, for example:
activeCount() : Returns the number of active threads in the current thread's thread group.
You can use this as a debug method.
isAlive() : Tests if this thread is alive.
To check if a specific thread is alive.
join() : Waits for this thread to die.
If you call this at the end of your method then it will wait for the thread to join (i.e. to end execution) before advancing. If you call for all threads, then you are sure that all have finished when the main() has finished.
destroy() : Destroys this thread, without any cleanup.
Does what it says, but I would never suggest this.
Hope it helps!
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 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.