浅聊 【ThreadLocal】(超级详细)

写在开始 :
本文主要讲述 : ThreadLocal简介; 常用API; demo案例; 特点引用场景;以及部分底层原理源码内容。

引言 :

从常见面试题看 ThreadLocal:
**①解释 **: ThreadLocal是多线程中对于解决线程安全的一个操作类,它会为每个线程都分
配一个独立的线程副本从而解决了变量并发访问冲突的问题。ThreadLocal 同时
实现了线程内的资源共享;
②案例:使用JDBC操作数据库时,会将每一个线程的Connection放入各自的
ThreadLocal中,从而保证每个线程都在各自的 Connection 上进行数据库的操
作,避免A线程关闭了B线程的连接。

public class ThreadLocalTest {
   
    static ThreadLocal<String> threadLocal = new ThreadLocal<>();
    
    public static void main(String[] args) {
   
        new Thread(() -> {
   
            String name = Thread.currentThread().getName();
            threadLocal.set("itcast"); // set(v)方法 : 设置值
            print(name);
            System.out.println(name + "-after remove : " +
            threadLocal.get());        // get()方法:获取值
        }, "t1").start();
        new Thread(() -> {
   
            String name = Thread.currentThread().getName();
            threadLocal.set("itheima");
            print(name);
            System.out.println(name + "-after remove : " +
            threadLocal.get());
        }, "t2").start();
    }
    static void print(String str) {
   
        //打印当前线程中本地内存中本地变量的值
        System.out.println(str + " :" + threadLocal.get());
        //清除本地内存中的本地变量
        threadLocal.remove();         // remove()方法 清除值
    }
}

③源码
ThreadLocal本质来说就是一个线程内部存储类,从而让多个线程只操作自己内
部的值,从而实现线程数据隔离;
image.png
在ThreadLocal中有一个内部类叫做ThreadLocalMap,类似于HashMap
ThreadLocalMap中有一个属性table数组,这个是真正存储数据的位置
Ⅰ:set方法:
image.png
Ⅱ:get/remove方法
image.png

内存泄漏问题
每一个Thread维护一个ThreadLocalMap,在ThreadLocalMap中的Entry对象继承
了WeakReference。其中key为使用弱引用的ThreadLocal实例,value为线程变量
的副本;
引用类型 : ①弱引用:内存不太够时候优先回收;②强引用:不会被回收
使用 ThreadLocal 时候 ,强烈建议:务必手动remove。

正文第一部分–编程实战

1.ThreadLocal 简介

ThreadLocal 见名知意 : 线程本地 或者 本次线程;
但是从它实际作用而言, 可能解释为 【线程局部变量】or 【线程本地变量】更为合适。

2.ThreadLocal作用

ThreadLocal是java.lang包中的一个泛型类,可以实现为线程创建独有变量,这个变量对于其他线程是隔离的,也就是线程本地的值,这也是ThreadLocal名字的来源;

package java.lang

public class ThreadLocal<T>{
   }

每个使用该变量的线程都要初始化一个完全独立的实例副本(也就是变量的本地拷贝),不存在多线程间共享问题

3.ThreadLocal的 API 方法

ThreadLocal用来存储当前线程的独有数据,相关API就是存值,取值,清空值的简单操作

  • withInitial:创建一个ThreadLocal实例,并给定初始值【JDK8推出的新方法,一般都是用该方法初始化ThreadLocal】
  • get:返回当前线程ThreadLocal的值,如果没有设置值返回null
  • set:设置当前线程ThreadLocal的值
  • remove:删除当前线程ThreadLocal的值
  • initialValue:此方法默认返回null, 通过ThreadLocal构造方法初始化时一般重写此方法,来设置初始值,在JDK8之后通过withInitial方法初始化

4.初始化ThreadLocal

初始化ThreadLocal有三种方式:

  • 直接通过构造方法创建,此时初始值为null
  • 通过构造方法同时重写initialValue方法给定初始值
  • 通过JDK8的withInitial()静态方法创建,可以通过Lambda直接给初始值【推荐使用】

①构造方法

@Test
public void test1() {
   
    // 通过构造方法,初始化ThreadLocal
    ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
    // 未给定初始值,通过get方法获取值为null
    System.out.println(threadLocal.get());
}


@Test
public void test2() {
   
    // 初始化ThreadLocal
    ThreadLocal<Integer> threadLocal = new ThreadLocal<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值