My limited understanding of ThreadLocal is that it has resource leak issues. I gather this problem can be remedied through proper use of WeakReferences with ThreadLocal (although I may have misunderstood this point.) I would simply like a pattern or example for correctly using ThreadLocal with WeakReference, if one exists. For instance, in this code snippet where would the WeakReference be introduced?
static class DateTimeFormatter {
private static final ThreadLocal<SimpleDateFormat> DATE_PARSER_THREAD_LOCAL = new ThreadLocal<SimpleDateFormat>() {
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy/MM/dd HH:mmz");
}
};
public String format(final Date date) {
return DATE_PARSER_THREAD_LOCAL.get().format(date);
}
public Date parse(final String date) throws ParseException
{
return DATE_PARSER_THREAD_LOCAL.get().parse(date);
}
}
Memory leak is caused when ThreadLocal is always existing. If ThreadLocal object could be GC, it will not cause memory leak. Because the entry in ThreadLocalMap extends WeakReference, the entry will be GC after ThreadLocal object is GC.
ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or transaction ID). The use of ThreadLocal objects requires care in classes whose objects are required to be executed by multiple threads in a thread pool.
You should always call remove because ThreadLocal class puts values from the Thread Class defined by ThreadLocal. Values localValues; This will also cause to hold reference of Thread and associated objects. the value will be set to null and the underlying entry will still be present.
In 2009, some JVMs implemented ThreadLocal using an unsynchronised HashMap in the Thread. currentThread() object. This made it extremely fast (though not nearly as fast as using a regular field access, of course), as well as ensuring that the ThreadLocal object got tidied up when the Thread died.
ThreadLocal
uses a WeakReference
internally. If the ThreadLocal
is not strongly referenced, it will be garbage-collected, even though various threads have values stored via that ThreadLocal
.
Additionally, ThreadLocal
values are actually stored in the Thread
; if a thread dies, all of the values associated with that thread through a ThreadLocal
are collected.
If you have a ThreadLocal
as a final class member, that's a strong reference, and it cannot be collected until the class is unloaded. But this is how any class member works, and isn't considered a memory leak.
Update: The cited problem only comes into play when the value stored in a ThreadLocal
strongly references that ThreadLocal
—sort of a circular reference.
In this case, the value (a SimpleDateFormat
), has no backwards reference to the ThreadLocal
. There's no memory leak in this code.
I'm guessing you're jumping through these hoops since SimpleDateFormat is not thread-safe.
Whilst I'm aware I'm not solving your problem above, can I suggest you look at Joda for your date/time work ? Joda has a thread-safe date/time formatting mechanism. You won't be wasting your time learning the Joda API either, as it's the foundation for the new standard date/time API proposal.
There shouldn't be such a problem.
A thread's ThreadLocal reference is defined to exist only as long as the corresponding thread is alive (see the javadoc)-- or put another way, once the thread is not alive, if the ThreadLocal was the only reference to that object, then the object becomes eligible for garbage collection.
So either you've found a genuine bug and should be reporting it, or you're doing something else wrong!
I realise this isn't strictly an answer to your question but as a general rule I won't suggest using a ThreadLocal
in situration where there isn't a clear tear down at the end of a request/interaction. The classic is doing this sort of thing in a servlet container, at first glance it seems fine, but since the threads are pooled it becomes a issue with the ThreadLocal
hanging onto the resource even after each request has been processed.
Suggestions:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With