How to correctly handle ThreadLocal.get() returning null
Java's ThreadLocal
s make certain things easy, but special care must be taken to make sure they are removed from threads when they are no longer needed. If ThreadLocal
s are not removed from threads, they can easily cause memory leaks, because threads can live much longer than the applications that are executed on a thread.
Consider a web application running inside a servlet container like Tomcat. Each request is handled by a thread from a thread pool. These threads can live well after you web app is undeployed from the server.
One of the easiest ways to get this wrong is to assume that ThreadLocal.get()
returning null
means that the ThreadLocal
is not installed in the thread. This is not the case.
Each thread has a map of ThreadLocal
s, and when ThreadLocal.get()
is called for the first time, it actually installs the ThreadLocal
into that ThreadLocal
map for the current thread with the default value, which is usually null
. You must still remove the ThreadLocal
from the thread by calling ThreadLocal.remove()
.
As a rule of thumb, for ThreadLocal
s where the default value is null, if get()
returns null
, remove()
should be called immediately.
I have written a class that does most of this for me:
/**
* A conservative {@link ThreadLocal} that removes itself from the thread
* whenever its value is {@code null}.
* @author Jesse Long
* @param <T> The type of the value stored in this {@link ThreadLocal}
*/
public abstract class ConservativeThreadLocal<T>
extends ThreadLocal<T>
{
/**
* Returns the current value of the variable, or {@code null} if it has not
* been set. This method takes care to remove this {@link ThreadLocal} from
* the thread if the value has not been set.
* @return the current value of the variable, or {@code null} if it has not
* been set.
*/
@Override
public final T get()
{
T t = super.get();
if (t == null){
remove();
}
return t;
}
/**
* Returns {@code null}. This implementation always returns {@code null} so
* that this {@link ThreadLocal} implementation can use its absent on a
* thread as an indication that the value is not set.
* @return {@code null}
*/
@Override
protected final T initialValue()
{
return null;
}
/**
* Returns the current value of the variable. If the value has not been
* set, and {@code create} is {@code true}, then the {@link #create()}
* method is called, the value of the {@link ThreadLocal} is set to the
* return value of {@link #create()}, and is returned from this method. If
* the value has not been set, and {@code create} is {@code false}, then
* this method behaves exactly the same as the {@link #get()} method.
*
* @return the current value of the variable, or the default value if
* {@code create} is {@code true}.
*
* @param create whether or not to set the default value if it has not yet
* been set.
*/
public T get(boolean create)
{
T t = get();
if (t == null && create){
t = create();
set(t);
}
return t;
}
/**
* Sets the current value. If {@code value} is {@code null}, then this
* {@link ThreadLocal} is removed from the thread.
* @param value The value to set.
*/
@Override
public void set(T value)
{
if (value == null){
remove();
}else{
super.set(value);
}
}
/**
* Returns the default value for this object.
* @return the default value for this object.
* @see #get(boolean)
*/
protected abstract T create();
}
How to correctly handle ThreadLocal.get() returning null的更多相关文章
- correctly handle PNG transparency in Win IE 5.5 & 6.
function correctPNG() // correctly handle PNG transparency in Win IE 5.5 & 6. { var arVersion = ...
- How to use System.Diagnostics.Process correctly
I’ve seen many a question on stackoverflow and other places about running a process and capturing it ...
- ThreadLocal以及内存泄漏
ThreadLocal是什么 ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度.但是如果滥用Thr ...
- Java -- 基于JDK1.8的ThreadLocal源码分析
1,最近在做一个需求的时候需要对外部暴露一个值得应用 ,一般来说直接写个单例,将这个成员变量的值暴露出去就ok了,但是当时突然灵机一动(现在回想是个多余的想法),想到handle源码里面有使用过Th ...
- ThreadLocal 原理
ThreadLocal是什么 ThreadLocal是一个本地线程副本变量工具类.主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用, ...
- 多线程之ThreadLocal类
深入研究java.lang.ThreadLocal类 0.前言 ThreadLocal(线程变量副本)Synchronized实现内存共享,ThreadLocal为每个线程维护一个本地变量.采用空间换 ...
- ThreadLocal 工作原理、部分源码分析
1.大概去哪里看 ThreadLocal 其根本实现方法,是在Thread里面,有一个ThreadLocal.ThreadLocalMap属性 ThreadLocal.ThreadLocalMap t ...
- JavaSe:ThreadLocal
JDK中有一个ThreadLocal类,使用很方便,但是却很容易出现问题.究其原因, 就是对ThreadLocal理解不到位.最近项目中,出现了内存泄漏的问题.其中就有同事在使用ThreadLocal ...
- ThreadLocal 源码剖析
ThreadLocal是Java语言提供的用于支持线程局部变量的类.所谓的线程局部变量,就是仅仅只能被本线程访问,不能在线程之间进行共享访问的变量(每个线程一个拷贝).在各个Java web的各种框架 ...
随机推荐
- leetcode - [4]Sort List
Sort a linked list in O(n log n) time using constant space complexity. 思路:采用归并排序或者快速排序 #include < ...
- linux ping命令
Linux系统的ping命令是常用的网络命令,它通常用来测试与目标主机的连通性,我们经常会说“ping一下某机器,看是不是开着”.不能打开网页时会说“你先ping网关地址192.168.1.1试试”. ...
- 如何打包maven项目
start 步骤1:项目右键-->Run As-->Maven clean 步骤2:Run As-->Maven install end
- POJ2112 Optimal Milking
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 17811 Accepted: 6368 ...
- 基于MATLAB的腐蚀膨胀算法实现
本篇文章要分享的是基于MATLAB的腐蚀膨胀算法实现,腐蚀膨胀是形态学图像处理的基础,腐蚀在二值图像的基础上做“收缩”或“细化”操作,膨胀在二值图像的基础上做“加长”或“变粗”的操作. 什么是二值图像 ...
- hdu 4920
http://acm.hdu.edu.cn/showproblem.php?pid=4920 给定两个n阶矩阵,求矩阵相乘后模3. 直接搞肯定会超时 特殊处理1和2的情况 实际上是水过的..... 貌 ...
- js-选项卡套选项卡
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- 深度学习主机环境配置: Ubuntu16.04+GeForce GTX 1080+TensorFlow
接上文<深度学习主机环境配置: Ubuntu16.04+Nvidia GTX 1080+CUDA8.0>,我们继续来安装 TensorFlow,使其支持GeForce GTX 1080显卡 ...
- [翻译] ASP.NET WebAPI 中的异常处理
原文链接:https://docs.microsoft.com/en-us/aspnet/web-api/overview/error-handling/exception-handling 本文介绍 ...
- 用Socket来简单实现IIS服务器
刚刚接触ASP.NET编程,为了更好的屡清楚服务器的处理过程,就用Socket模拟服务器来处理请求.用Socket来模拟服务器的时候,同样是自己来封装一些对应的类文件.包括 HttpRequest.H ...