juc之ThreadLocal

并发工具类——分类

在这里插入图片描述

ThreadLocal

使用场景

在这里插入图片描述

典型场景1:初始化ThreadLocal,使得不安全的工具类线程安全

public static ThreadLocal<SimpleDateFormat> dateFormatThreadLocal 
= ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
public static ThreadLocal<SimpleDateFormat> dateFormatThreadLocal = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

在这里插入图片描述

典型场景2: 使用set在ThreadLocal中存入全局变量,在其他方法中使用get读取,避免参数传递

ThreadLocal的两个作用

在这里插入图片描述

ThreadLocal的好处

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

原理

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

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;ThreadLocalMap
            }
        }
        return setInitialValue();
    }
  • 每个线程都有一个对应的ThreadLocalMap,在get方法中先获取当前线程对应的ThreadLocalMap,ThreadLocalMap中的键值对是当前的ThreadLocalMap和对应的内容,所以可以通过map.getEntry(this)获取对应的内容。
public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
  • set方法与get方法相反

主要方法介绍

initialValue

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

void set(T t) 和 T get()

在这里插入图片描述

void remove()

在这里插入图片描述

ThreadLocal注意点

内存泄露

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

空指针异常

在这里插入图片描述

public class Main {
    public static void main(String[] args) {
        System.out.println(ThreadLocalUtil.get());
    }
}

class ThreadLocalUtil {
    public static ThreadLocal<Long> longThreadLocal = new ThreadLocal<>();

    public static void set(Long num) {
        longThreadLocal.set(num);
    }

    public static long get() {
        return longThreadLocal.get();
    }

    public static void remove() {
        longThreadLocal.remove();共享对象
    }
}

以上代码会导致空指针异常,而不会输出null,这是因为get方法返回时进行了拆箱,无法对null进行拆箱,导致空指针异常。

其他注意点

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210708在这里插入图片描述
在这里插入图片描述

实际应用场景

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值