Java——》ThreadLocal

推荐链接:

总结------》【Java】

总结------》【Mysql】

总结------》【Redis】

总结------》【Kafka】

总结------》【Spring】

总结------》【SpringBoot】

总结------》【MyBatis、MyBatis-Plus】

总结------》【Linux】

总结------》【MongoDB】

总结------》【Elasticsearch】

Java------》ThreadLocal

一、概念

ThreadLocal可以理解为线程本地变量,他会在每个线程都创建一个副本,那么在线程之间访问内部副本变量就行了,做到了线程之间互相隔离,相比于synchronized的做法是用空间来换时间。

ThreadLocal的本质就是一个Map,ThreadLocal做为key,将一个数据和本地线程绑定在一起。

二、源码

ThreadLocal有一个静态内部类ThreadLocalMap,ThreadLocalMap又包含了一个Entry数组,Entry本身是一个弱引用,他的key是指向ThreadLocal的弱引用,Entry具备了保存key value键值对的能力。

三、内部结构

四、特点

  • 每个Thread中都存储着一个成员变量ThreadLocalMap
  • ThreadLocal本身不存储数据,像是一个工具类,基于ThreadLocal去操作ThreadLocalMap
  • ThreadLocalMap本身就是基于Entry[]实现的,因为一个线程可以绑定多个ThreadLocal,这样一来,可能需要存储多个数据,所以采用Entry[]的形式实现。
  • 每一个现程都自己独立的ThreadLocalMap,再基于ThreadLocal对象本身作为key,对value进行存取
  • ThreadLocalMap的key是一个弱引用,弱引用的目的是为了防止内存泄露,如果是强引用那么ThreadLocal对象除非线程结束否则始终无法被回收,弱引用则会在下一次GC的时候被回收

五、内存泄漏问题

Java中4种引用:

强引用:OOM也不清除

软引用:内存不足清除

弱引用:只要GC就清除

虚引用:拿不到引用,构建出来就凉凉~~

1、现象

假如ThreadLocal对象被回收之后,key因为弱引用也会被GC回收掉,同时线程还没有被回收,entry中就存在key为null,但value有值的entry对象,但是内存中的value无法被获取到,同时也无法被回收,就会导致内存泄漏。

2、解决方案

使用TheadLocal完毕后,调用remove方法删除Entry对象

六、内存泄漏案例

参考链接:Java------》内存泄露案例

七、保证原子性

ThreadLocal保证原子性的方式,是不让多线程去操作临界资源让每个线程去操作属于自己的数据

java 复制代码
static ThreadLocal tl1 = new ThreadLocal();
static ThreadLocal tl2 = new ThreadLocal();

public static void main(String[] args) {
    tl1.set("123");
    tl2.set("456");
    Thread t1 = new Thread(() -> {
        System.out.println("t1:" + tl1.get());
        System.out.println("t1:" + tl2.get());
    });
    t1.start();

    System.out.println("main:" + tl1.get());
    System.out.println("main:" + tl2.get());
}
相关推荐
天天摸鱼的java工程师13 小时前
领导:“线程池又把服务器搞崩了!” 八年 Java 开发:按业务 + 服务器配,从此稳抗大促
java·后端
初级程序员Kyle13 小时前
开始改变第四天 Java并发(2)
java·后端
SimonKing13 小时前
【开发者必备】Spring Boot 2.7.x:WebMvcConfigurer配置手册来了(六)!
java·后端·程序员
caimo14 小时前
Java无法访问网址出现Timeout但是浏览器和Postman可以
java·开发语言·postman
Deamon Tree14 小时前
ElasticSearch架构和写入、更新、删除、查询的底层逻辑
java·大数据·elasticsearch·架构
北极糊的狐14 小时前
IntelliJ IDEA插件:CodeGeeX 智能助手插件
java·ide·intellij-idea
悟能不能悟14 小时前
jdk25结构化并发和虚拟线程如何配合使用?有什么最佳实践?
java·开发语言
熙客15 小时前
Java8:Lambda表达式
java·开发语言
小咕聊编程15 小时前
【含文档+PPT+源码】基于java web的篮球馆管理系统系统的设计与实现
java·开发语言
后端小张15 小时前
【JAVA 进阶】Mybatis-Plus 实战使用与最佳实践
java·spring boot·spring·spring cloud·tomcat·mybatis·mybatis plus