Say I have an object "MyObj" that runs a repeated thread and I place this object within a hash-map.
If I then remove the entry for that object, will this kill the thread? Or do I need to kill the thread before removing the object?
Removing an object from a HashMap will do nothing to the thread, and it will continue to run unless you explicitly stop it.
From Java Memory Management
Active Java threads are always considered live objects and are therefore GC roots. This is especially important for thread local variables
An object must be unreachable and have no GC roots to be considered for GC'ing.
Related
I have a Java class which needs a monitor running parallel when instantiated. I want to keep running this monitor until the instance is not running any more or it is not referenced.
Usually I tend to use a active flag as a variable, which is closed when the class is shutdown/closed, however this has to be managed carefully and it has to be called when closing.
I am also aware of the finalize member of Object but as I remember it is not safe to use it or is it for this purpose?
Additionally a monitor might have circular references to the monitored object of course, but this might be an other issue.
You could like the object to be monitored in the thread using a WeakReference. This allows the garbage collector to collect and destroy the object.
In the thread you would have to check each time if the referenced object still exists every time you perform your checks. If it no longer exists you can safely exit the thread.
As the garbage collector does not immediately destroy objects there may be an unknown time span where the tread is still active but the monitored object is no longer used.
I am considering extending java.util.Timer, and completely overriding all public methods, to use a different implementation. The one "problem" I see is, that Timer instantiate and starts a Thread in it's constructor, which I cannot use, due to it being "private". So I would like to not waste the "resources" used up by that Thread. I see at least one things I could do, which is to call super.cancel() directly in the sub-class constructor, thereby immediately closing the thread.
My question is: When are the "resources" of a java.lang.Thread allocated and released?
Allocation: At instance instantiation, or at call of start()?
Release: At "end of run()" or at instance GC time?
If it's JVM implementation specific, I'd like to know how the Oracle JVM does it?
Generally, when you instantiate an object you allocate space in memory for it. This is the case when you create a Thread object as well. It is making perfect sense, as you might wonder how can you use an object which is not stored in the memory. A Thread object does not use a lot of memory though. On the other hand, when you call the start() method the run() method of the Runnable is called and all the resources associated to the Thread will be allocated there. If the Thread is no longer running, then all the otherwise unreferenced resources used by the Thread will be de-allocated by the garbage collector eventually. So, if you ask me I think your approach to stop the Thread is good, this way only the Thread object will remain in the memory along with any other resources you reference.
I'm starting my thread like so:
(new MyThread()).start();
I'm not keeping a reference to it anywhere, so I'm wondering if it's a safe approach - can't GC collect it since it's not referenced?
If not (I think so), then why?
If you look at the OpenJDK Java 7 source code of Thread, you'll notice that start() contains the following
group.add(this);
where group is the Thread's ThreadGroup which is managed by the JVM. So there is always a reachable reference to the Thread while it is still running. It won't be garbage collected
If this alone isn't convincing, consider that starting a new thread means creating a new call stack where the root call is one of Thread's methods, probably some native method. You can't be executing the method of an object if the object is garbage collected. As such, the Thread object must still be alive.
class Clstest{
public static String testStaticMethod(String inFileStr) {
// section 0
// section 1
// do something with inFileStr
// section 2
// section 3
return inFileStr;
}
}
Let's assume there are five threads are each executing a call to Clstest.testStaticMethod("arg-n") at the same time.
Thread 1 calls Clstest.testStaticMethod("arg-1").
When thread 1 is in the section 1, thread 2 calls Clstest.testStaticMethod("arg-2").
Then what will happen to Thread 1? Will it go to sleep state?
When Thread 1 got the chance will it resume the execution from section 1 where it was paused?
How it happens when there's one Clstest.testStaticMethod and same Clstest.testStaticMethod is shared between all five threads?
Is there any possibility to interchange the inFileStr sent by multiple threads?
Hans Passant's answer is good. But I thought I would try and explain at a slightly more simple level for anybody who comes across this and is newish to Java. Here goes..
Memory in java is split up into two kinds - the heap and the stacks. The heap is where all the objects live and the stacks are where the threads do their work. Each thread has its own stack and can't access each others stacks. Each thread also has a pointer into the code which points to the bit of code they're currently running.
When a thread starts running a new method it saves the arguments and local variables in that method on its own stack. Some of these values might be pointers to objects on the heap. If two threads are running the same method at the same time they will both have their code pointers pointing at that method and have their own copies of arguments and local variables on their stacks. They will only interfere with each other if the things on their stacks point to the same objects on the heap. In which case all sorts of things might happen. But as Hans points out, Strings are immutable (cannot be changed) so we're safe if this is the only object being "shared".
So many threads can be running the same method. They might not be running at the same time - it depends how many cores you have on your machine as the JVM maps Java threads to OS threads, which are scheduled onto hardware threads. You therefore have little control over the way these threads interleave without using complex synchronisation mechanisms.
Note that sleeping is something a thread does to itself.
Will it go to sleep state?
No, running a thread does not affect other threads as long as they don't intentionally synchronize with each other. If you have more than one processor core, all recent machines do, those threads are likely to execute at the exact same time. That gets to be bit less likely when you start 5 threads since your machine might not have enough cores. The operating system is forced to choose between them, giving them each some time to run. The job of the thread scheduler. A thread will then not be in a "sleep" state, it is simply paused and waiting for the thread scheduler to give it a chance to run. It will resume where it was interrupted by the scheduler.
Is there any possibility to interchange the inFileStr sent by multiple threads?
There is no such possibility, threads have their own stack so any method argument and local variable will be unique for each thread. Using a string furthermore guarantees that these threads cannot interfere with each other since strings are immutable.
There's no such guarantee if the argument is a reference to another kind of mutable object. Or if the method itself uses variables that are static or references to objects on the heap. Synchronization is required when a thread modifies the object and another thread reads it. The lock keyword in the C# language is the boilerplate way to implement such required synchronization. The fact that the method is static does not mean such synchronization is never required. Just less likely since you don't have to worry about threads accessing the same object (sharing this).
I'm writing a chat server in Java. I was using a fixed array of runnable classes where each element in array represents a client. The threads created are in an infinite loop which reads from socket stream.
Now I want to do it with a list so I don't have to worry about array size and it sounds more legit way of doing it. However I couldn't be sure if removing an item also terminates the thread. Actually I have no idea what it does. Also, I'm wondering is there any other possible issues with using list in that kind of situaton. Finally, how about array of Timer? Since I've used Timer for each client, again, does removing a Timer from a Timer list also stops its schedule? Any possible problems?
An object exists in itself - storing a reference to that object in a list does not change its behaviour.
So if you have a Runnable task which is running in a thread, adding it to / removing it from a list does not make a difference to that Runnable and the thread will continue running it.
The same applies to a Timer and any other objects.
Side note: there is one situation where removing an object from a list can make a difference: it is if that object is only reachable through that list. After being removed, because it is not reachable any longer, it becomes eligible for garbage collection. But that does not apply to a running thread or active timer.
You have a thread object. A reference to it was inserted into an array. Adding or removing the reference from the array (i.e. the thread) is not going to cause any unknown side effects, so you are good. If you want to stop the thread you will have to implement that either internally in your run method. Garbage collection is not an issue here.
Timer's the same issue again: they are all object references.
A running thread is considered a so called garbage collection root. Anything that is a root or can be (indirectly) referenced from the root will not be garbage collected. When the garbage collector determines whether your object is 'reachable' or not, it is always doing so using the set of garbage collector roots as reference points.
Hey there i will refer to this question!
If the thread is started it will not garbage collected as it is referenced by the containing thread.
It will garbage collected if it is done or not started yet!
The reason for this is, when started the thread-object gets added to the current ThreadGroup (a bit more complex under the hood :) ) and when its done it will automatically removed.