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 nullremove() 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的更多相关文章

  1. correctly handle PNG transparency in Win IE 5.5 & 6.

    function correctPNG() // correctly handle PNG transparency in Win IE 5.5 & 6. { var arVersion = ...

  2. 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 ...

  3. ThreadLocal以及内存泄漏

    ThreadLocal是什么 ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度.但是如果滥用Thr ...

  4. Java -- 基于JDK1.8的ThreadLocal源码分析

    1,最近在做一个需求的时候需要对外部暴露一个值得应用  ,一般来说直接写个单例,将这个成员变量的值暴露出去就ok了,但是当时突然灵机一动(现在回想是个多余的想法),想到handle源码里面有使用过Th ...

  5. ThreadLocal 原理

    ThreadLocal是什么 ThreadLocal是一个本地线程副本变量工具类.主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用, ...

  6. 多线程之ThreadLocal类

    深入研究java.lang.ThreadLocal类 0.前言 ThreadLocal(线程变量副本)Synchronized实现内存共享,ThreadLocal为每个线程维护一个本地变量.采用空间换 ...

  7. ThreadLocal 工作原理、部分源码分析

    1.大概去哪里看 ThreadLocal 其根本实现方法,是在Thread里面,有一个ThreadLocal.ThreadLocalMap属性 ThreadLocal.ThreadLocalMap t ...

  8. JavaSe:ThreadLocal

    JDK中有一个ThreadLocal类,使用很方便,但是却很容易出现问题.究其原因, 就是对ThreadLocal理解不到位.最近项目中,出现了内存泄漏的问题.其中就有同事在使用ThreadLocal ...

  9. ThreadLocal 源码剖析

    ThreadLocal是Java语言提供的用于支持线程局部变量的类.所谓的线程局部变量,就是仅仅只能被本线程访问,不能在线程之间进行共享访问的变量(每个线程一个拷贝).在各个Java web的各种框架 ...

随机推荐

  1. shell脚本-成长之路

    我对shell脚本的认识,除了执行过同事写的shell 脚本外,其他一无所知,为了让自己强大,我决定自己研究shell脚本,也许在你看来很简答,没必要说这么多废话,但是我希望在我的技术log里记录下来 ...

  2. web-day2

    第2章WEB02-CSS&JS篇 今日任务 使用CSS完成网站首页的美化 使用CSS完成网站注册页面的美化 使用JS完成简单的数据校验 使用JS完成图片轮播效果 教学导航 教学目标 了解CSS ...

  3. mysql同时使用order by和limit查询时的一个严重隐患 -- 丢失数据

    转自: https://blog.csdn.net/tsxw24/article/details/44994835 我经常使用order by和limit来做数据分页显示并排序,一直也没发现过什么问题 ...

  4. Android 如何通过浏览器打开App

    首先给出参考资料http://my.oschina.net/liucundong/blog/354029?p=3#rpl_291191828 通过浏览器直接打开Android应用程序 Android ...

  5. c# json转换成dynamic对象,然后在dynamic对象中动态获取指定字符串列表中的值

    using Newtonsoft.Json;using System;using System.Collections.Generic;using System.Linq;using System.T ...

  6. TTL与CMOS门电路

    个人观点总结 对TTL和CMOS门电路的认识: 1.构成 TTL集成电路一般都是有三极管(或二极管)和电阻.电容构成,其中三极管(二极管)是作为主要的开关器件 CMOS集成电路一般是由场效应管和电阻. ...

  7. ORACLE ERP consolidation流程(一)

    原文地址:ORACLE ERP consolidation流程(一) 作者:wolfyuan ORACLE EBS by transaction consolidation的详细流程(一)[@more ...

  8. ThreadLocal实现线程级上下文

    一.ThreadLocal测试 package com.junge.threadlocal.context; /** * @author Administrator * */ public class ...

  9. Linux-用户及权限

    1. 用户组 RHEL 7/CentOS 7系统中的用户组有如下3类: 超级用户,UID 0:系统的超级用户. 系统用户,UID 1-999:系统中系统服务由不同用户运行,更加安全,默认被限制不能登录 ...

  10. kotlin面向对象-笔记