A Sonar rule available since Aug 21, 2019 (squid:S5164 / RSPEC-5164) mandates to clean up "ThreadLocal" variables when no longer used. So, let's take the following class (JDK6 compatible):
public class ThreadLocalExample {
private static final ThreadLocal<NumberFormat> formats = new ThreadLocal<NumberFormat>() {
@Override
protected NumberFormat initialValue() {
final NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
nf.setMinimumFractionDigits(2);
nf.setMaximumFractionDigits(2);
nf.setGroupingUsed(false);
return nf;
}
};
public static NumberFormat getFormatter() {
return formats.get();
}
}
Sonar reports a major bug on the ThreadLocal
declaration, with the following explanation:
"ThreadLocal" variables should be cleaned up when no longer used
ThreadLocal
variables are supposed to be garbage collected once the holding thread is no longer alive. Memory leaks can occur when holding threads are re-used which is the case on application servers using pool of threads.To avoid such problems, it is recommended to always clean up
ThreadLocal
variables using theremove()
method to remove the current thread’s value for theThreadLocal
variable.
Now, I adopted the ThreadLocal
approach in order to reuse NumberFormat
instances as much as possible, avoiding the creation of one instance per call, so I think if I called remove()
somewhere in the code, I would lose all the advantages of this solution. Am I missing something? Thanks a lot.