Java基础回顾:ThreadLocal

1. 是什么
是一个数据结构,有点像HashMap,可以保存"key : value"键值对,但是一个ThreadLocal只能保存一个,并且各个线程的数据互不干扰。
作用:在多线程环境下,如何防止自己的变量被其它线程篡改
2. 如何实现线程隔离
  • 每个线程中维护一个ThreadLocalMap数据结构,当执行set方法时,其值是保存在当前线程的threadLocals变量中,当执行get方法中,是从当前线程的threadLocals(ThreadLocal.ThreadLocalMap类)变量获取。
  • 所以在线程1中set的值,对线程2来说是接触不到的,而在线程2中重新set的话,也不会影响到线程1中的值,保证了线程之间不会互相干扰。
3. ThreadLocalMap
类HashMap的数据结构,但是并没有实现Map的接口。
在ThreadLocalMap中,也是初始化一个大小为16的Entry数组,Entry对象用来保存每一个key-value键值对,只不过这里的key永远都是ThreadLocal对象。Entry中不存在链表。
hash冲突?找下一个空位置
4. 为什么会导致内存泄漏,如何避免?
当使用ThreadLocal保存一个value时,会在ThreadLocalMap中的数组插入一个Entry对象,在ThreadLocalMap的实现中,Entry的key是ThreadLocal对象的弱引用。ThreadLocal在没有外部强引用时,发生GC时会被回收,如果创建ThreadLocal的线程一直持续运行,那么这个Entry对象中的value就有可能一直得不到回收,发生内存泄漏。
如何避免:1. 显示的调用remove方法
 
注:内存泄漏:内存申请后,用完没有释放,造成可用内存越来越少,即无法释放已申请的内存。
 
5. 主要应用场景
数据库管理类
session管理
// 阿里巴巴 java 开发手册中推荐的 ThreadLocal 的用法:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
 
public class DateUtils {
    public static final ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(){
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };
}
// 然后我们再要用到 DateFormat 对象的地方,这样调用
// DateUtils.df.get().format(new Date());
 
多线程测试
 

posted @ 2021-10-13 22:35  fanghuiX  阅读(52)  评论(0编辑  收藏  举报