Run thread until object/parent is dereferenced - java

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.

Related

Java threads within a hashmap

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.

At which point in the lifecycle is the "stack" of a Java Thread created and destroyed?

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.

Safe to start thread without keeping 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.

ThreadLocal garbage collection

From javadoc
Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist).
from that it seems that objects referenced by a ThreadLocal variable are garbage collected only when thread dies. But what if ThreadLocal variable a is no more referenced and is subject for garbage collection? Will object references only by variable a be subject to garbage collection if thread that holds a is still alive?
for example there is following class with ThreadLocal variable:
public class Test {
private static final ThreadLocal a = ...; // references object b
}
This class references some object and this object has no other references to it. Then during context undeploy application classloader becomes a subject for garbage collection, but thread is from a thread pool so it does not die. Will object b be subject for garbage collection?
TL;DR : You cannot count on the value of a ThreadLocal being garbage collected when the ThreadLocal object is no longer referenced. You have to call ThreadLocal.remove or cause the thread to terminate
(Thanks to #Lii)
Detailed answer:
from that it seems that objects referenced by a ThreadLocal variable are garbage collected only when thread dies.
That is an over-simplification. What it actually says is two things:
The value of the variable won't be garbage collected while the thread is alive (hasn't terminated), AND the ThreadLocal object is strongly reachable.
The value will be subject to normal garbage collection rules when the thread terminates.
There is an important third case where the thread is still live but the ThreadLocal is no longer strongly reachable. That is not covered by the javadoc. Thus, the GC behaviour in that case is unspecified, and could potentially be different across different Java implementations.
In fact, for OpenJDK Java 6 through OpenJDK Java 8 (and other implementations derived from those code-bases) the actual behaviour is rather complicated. The values of a thread's thread-locals are held in a ThreadLocalMap object. The comments say this:
ThreadLocalMap is a customized hash map suitable only for maintaining thread local values. [...] To help deal with very large and long-lived usages, the hash table entries use WeakReferences for keys. However, since reference queues are not used, stale entries are guaranteed to be removed only when the table starts running out of space.
If you look at the code, stale map entries (with broken WeakReferences) may also be removed in other circumstances. If stale entry is encountered in a get, set, insert or remove operation on the map, the corresponding value is nulled. In some cases, the code does a partial scan heuristic, but the only situation where we can guarantee that all stale map entries are removed is when the hash table is resized (grows).
So ...
Then during context undeploy application classloader becomes a subject for garbage collection, but thread is from a thread pool so it does not die. Will object b be subject for garbage collection?
The best we can say is that it may be ... depending on how the application manages other thread locals the thread in question.
So yes, stale thread-local map entries could be a storage leak if you redeploy a webapp, unless the web container destroys and recreates all of the request threads in the thread pool. (You would hope that a web container would / could do that, but AFAIK it is not specified.)
The other alternative is to have your webapp's Servlets always clean up after themselves by calling ThreadLocal.remove on each one on completion (successful or otherwise) of each request.
ThreadLocal variables are hold in Thread
ThreadLocal.ThreadLocalMap threadLocals;
which is initialized lazily on first ThreadLocal.set/get invocation in the current thread and holds reference to the map until Thread is alive. However ThreadLocalMap uses WeakReferences for keys so its entries may be removed when ThreadLocal is referenced from nowhere else. See ThreadLocal.ThreadLocalMap javadoc for details
If the ThreadLocal itself is collected because it's not accessible anymore (there's an "and" in the quote), then all its content can eventually be collected, depending on whether it's also referenced somewhere else and other ThreadLocal manipulations happen on the same thread, triggering the removal of stale entries (see for example the replaceStaleEntry or expungeStaleEntry methods in ThreadLocalMap). The ThreadLocal is not (strongly) referenced by the threads, it references the threads: think of ThreadLocal<T> as a WeakHashMap<Thread, T>.
In your example, if the classloader is collected, it will unload the Test class as well (unless you have a memory leak), and the ThreadLocal a will be collected.
ThreadLocal contains a reference to a WeakHashMap that holds key-value pairs
It depends, it will not be garbage collected if your are referencing it as static or by singleton and your class is not unloaded, that is why in application server environment and with ThreadLocal values, you have to use some listener or request filter the be sure that you are dereferencing all thread local variables at the end of the request processing. Or either use some Request scope functionality of your framework.
You can look here for some other explanations.
EDIT: In the context of a thread pool as asked, of course if the Thread is garbaged thread locals are.
Object b will not be subject for garbage collection if it somehow refers to your Test class. It can happen without your intention. For example if you have a code like this:
public class Test {
private static final ThreadLocal<Set<Integer>> a =
new ThreadLocal<Set<Integer>>(){
#Override public Set<Integer> initialValue(){
return new HashSet<Integer>(){{add(5);}};
}
};
}
The double brace initialization {{add(5);}} will create an anonymous class which refers to your Test class so this object will never be garbage collected even if you don't have reference to your Test class anymore. If that Test class is used in a web app then it will refer to its class loader which will prevent all other classes to be GCed.
Moreover, if your b object is a simple object it will not be immediately subject for GC. Only when ThreadLocal.ThreadLocalMap in Thread class is resized you will have your object b subject for GC.
However I created a solution for this problem so when you redeploy your web app you will never have class loader leaks.

Does removing an item from a list of class extending runnable terminates its thread?

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.

Categories

Resources