How to correctly handle ThreadLocal.get() returning null
Java's ThreadLocals 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 ThreadLocals 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 ThreadLocals, and when ThreadLocal.get() is called for the first time, it actually installs the ThreadLocalinto 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 ThreadLocals 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的各种框架 ...
随机推荐
- 20155326 2016-2017-2 《Java程序设计》第6周学习总结
20155326 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 InputStream与OutputStream: 串流设计的概念 (1)Java将输入/输 ...
- 马士兵hibernate(原始笔记)
马士兵hibernate(原始笔记) 课程内容 1 HelloWorld a) Xml b) annotation 2 Hibernate原理模拟 - 什么是O/R ...
- POJ3177tarjan缩点_构建双连通图
POJ3177tarjan缩点_构建双连通图 根据题意利用tarjan算法进行缩点处理后变成连通无环图,也可以说是一颗树,而且边是双向的所以,如果把这个图变成双连通,那就要对所有度为1的点进行加边处理 ...
- Git和SourceTree配合使用
Git介绍 git是当今最强大的本地的分布式代码版本管理工具. git的核心概念与操作:开发环境,本地仓库,远程仓库.他们的关系如下图: 与CVS及SVN的比较: CVS及SVN都是集中式的版本控制系 ...
- 测试pc大、小端
判断计算机的大.小端存储方式 1 int main() { ; char* p=(char*)&a; ) printf("little\n");//小端存储:高位存在地地址 ...
- Delphi 内进行音量控制及静音
unit UMute; interface uses MMSystem, Dialogs; Type TDeviceName = (Master, Microphone, WaveOut, Syn ...
- JS学习笔记1_基础与常识
1.六种数据类型 5种基础的:Undefined,Null,Boolean,Number,String(其中Undefined派生自Null) 1种复杂的:Object(本质是一组无序键值对) 2.字 ...
- VS2015中不同开发环境设置转换(C#->C++等)
backup VS2015 社区版(Community)下载地址:迅雷下载:ed2k://|file|cn_visual_studio_community_2015_x86_dvd_6847368.i ...
- ASP.NET MVC高亮显示当前页面菜单
1.创建MvcHtmlExtension扩展类 public static class MvcHtmlExtension { public static MvcHtmlString MenuLink( ...
- 纸壳CMS主题增强,支持主题中加入模板
背景 在之前,纸壳CMS的主题仅仅只是CSS样式,并不支持在主题下使用模板来构建不同的HTML结构.现在我们对主题功能做了增强,可以在主题下添加各自的模板,这样在制作主题时,就会更加自由.不仅如此,新 ...