ThreadLocal

ThreadLocal

作用:

  • 提供线程内局部变量,多线程场景下不同线程之间不会相互干扰。
  • ThreadLocal 实例通常来说都是 private static 修饰的,用于关联线程、线程上下文。
  • 减少同一个线程内的函数 或 组件之间传递变量的复杂性。

基本方法:

demo:

ThreadLocal处理多线程问题,将变量与线程绑定:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class ThreadLocalDemo {
    private String Msg;
    ThreadLocal<String> threadLocal = new ThreadLocal<>();
    private String getMsg(){
        return threadLocal.get();
    }
    private void setMsg(String s){
        threadLocal.set(s);
    }
    public static void main(String[] args) {
        ThreadLocalDemo threadLocalDemo = new ThreadLocalDemo();
        for(int i =0;i<10;i++){
            Thread thread = new  Thread(new Runnable() {
                @Override
                public void run() {
                    threadLocalDemo.setMsg(Thread.currentThread().getName()+"的数据");
                    System.out.println("--------------------------------------");
                    System.out.println(Thread.currentThread().getName()+", 保存的数据------>" + threadLocalDemo.getMsg());
                }
            });
            thread.start();
        }
    }
}

 运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Thread-0, 保存的数据------>Thread-0的数据
--------------------------------------
Thread-1, 保存的数据------>Thread-1的数据
--------------------------------------
Thread-2, 保存的数据------>Thread-2的数据
--------------------------------------
Thread-3, 保存的数据------>Thread-3的数据
--------------------------------------
Thread-4, 保存的数据------>Thread-4的数据
--------------------------------------
Thread-5, 保存的数据------>Thread-5的数据
--------------------------------------
Thread-6, 保存的数据------>Thread-6的数据
--------------------------------------
Thread-7, 保存的数据------>Thread-7的数据
--------------------------------------
Thread-9, 保存的数据------>Thread-9的数据
--------------------------------------
Thread-8, 保存的数据------>Thread-8的数据

验证可知,每个线程拿到的都是自己的数据。

ThreadLocal数据结构:

ThreadLocal的设计是:每个Thread维护一个ThreadLocalMap哈希表,这个哈希表的key是ThreadLocal实例本身,value才是真正要存储的值Object。
​ (1) 每个Thread线程内部都有一个Map (ThreadLocalMap)
​ (2) Map里面存储ThreadLocal对象(key)和线程的变量副本(value)
​ (3) Thread内部的Map是由ThreadLocal维护的,由ThreadLocal负责向map获取和设置线程的变量值。
​ (4) 对于不同的线程,每次获取副本值时,别的线程并不能获取到当前线程的副本值,形成了副本的隔离,互不干扰。

 

ThreadLocal可能引起的问题:

内存泄漏

问题背景:

 

  • 源码可知,在ThreadLocalMap中,用Entry来保存K-V结构数据的。但是Entry中key是ThreadLocal对象。
  • 源码可知,Entry继承WeakReference,使用弱引用,可以将ThreadLocal对象的生命周期和线程生命周期解绑。
  • 强引用( “Strong” Reference) , 最常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还“活着”,垃圾回收器就不会回收这种对象。
  • 弱引用( WeakReference) ,垃圾回收器发现只具有弱引用的对象,无论当前内存空间足够与否,都会回收。

 

问题原因:在当前线程依旧运行情况下,业务代码中使用完线程的ThreadLocal对象后被回收,则TheadLocalMap中Entry的key为null,此时Entry中value依然存在,且key为null,则value无法被访问到,内存泄漏。

 

处理方式:使用完ThreadLocal ,手动调用其remove方法删除对应的Entry。

 

 

 

 

 
 
 
 
 
 
 
 
 
 
 
posted @   Marktowin  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示