ThreadLocal知识点

前言

线程隔离:在多线程并发的场景下,线程中的每个变量都相互独立

一、ThreadLocal入门案例。

public class MyLocalThread {
    ThreadLocal<String> myLocalThread = new ThreadLocal<>();
    private String content;
    public String getContent() {
        return myLocalThread.get();
    }
    public void setContent(String content) {
        myLocalThread.set(content);
    }
    public static void main(String[] args) {
        MyLocalThread myLocalThread = new MyLocalThread();
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                myLocalThread.setContent(Thread.currentThread().getName());
                System.out.println("--------------------------");
                System.out.println("线程名字:" + Thread.currentThread().getName() + "----->内容:" + myLocalThread.getContent());
            }, i + "").start();
        }
    }

}

在这里插入图片描述

//这样是有问题的
public class MyLocalThread {
    private String content;
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }

    public static void main(String[] args) {
        MyLocalThread myLocalThread = new MyLocalThread();
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                myLocalThread.setContent(Thread.currentThread().getName() + "的线程");
                System.out.println("--------------------------");
                System.out.println("线程名字:" + Thread.currentThread().getName() + "----->内容:" + myLocalThread.getContent());
            }, i + "").start();
        }
    }
}

在这里插入图片描述

二、synchronized 与ThreadLocal 的区别。

synchronized 时间换空间 让每个线程排队访问,串行
ThreadLocal 空间换时间,让每个线程之间数据相互隔离,互不干扰,每个线程都有一个变量副本,并行

三、ThreadLocal 的优势。

1、传递数据︰保存每个线程绑定的数据,在需要的地方可以直接获取,避免参数直接传递带来的代码耦合问题
2、线程隔离∶各线程之间的数据相互隔离却又具备并发性,避免同步方式带来的性能损失

四、ThreadLocal 内部结构

常见误解:ThreadLocal 底层是不是一个map,早期是map。线程作为key,要存储的局部变量作为val。

在这里插入图片描述

myLocalThread.set(content); 方法

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }
//对应得 key value
        ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
            table = new Entry[INITIAL_CAPACITY];
            int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
            table[i] = new Entry(firstKey, firstValue);
            size = 1;
            setThreshold(INITIAL_CAPACITY);
        }

( 2)代码执行流程
A.首先获取当前线程,并根据当前线程获取一个Map
B.如果获取的Map不为空,则将参数设置到Map中(当前ThreadLocal的引用作为key )
C.如果Map为空,则给该线程创建Map ,并设置初始值

myLocalThread.get(); 方法

    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }

总结: **先获取当前线程的ThreadLocalMap变量,如果存在则返回值,不存在则创建并返回初始值。

initialValue() 方法

   private T setInitialValue() {
        T value = initialValue();
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
        return value;
    }
    protected T initialValue() {
        return null;
    }

五、内存溢出和内存泄漏 概念

内存溢出:(out of memory)通俗理解就是内存不够,通常在运行大型软件或游戏时,软件或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。

内存泄漏:(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果

六、ThreadLocal正确的使用方法

每次使用完ThreadLocal都调用它的remove()方法清除数据
将ThreadLocal变量定义成private static,这样就一直存在ThreadLocal的强引用,也就能保证任何时候都能通过ThreadLocal的弱引用访问到Entry的value值,进而清除掉

七、实战

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值