首页 > 其他分享 >ThreadLocal

ThreadLocal

时间:2024-02-23 18:12:28浏览次数:15  
标签:Java 对象 ThreadLocal GC 引用 线程

前置知识
Java中有些引用类型?
Java中主要有4种引用类型,分别是:强、软、弱、虚。他们主要跟Java的垃圾回收机制有关
强引用:Java中默认的引用类型,一个对象如果具有强引用,那么只要这种引用还存在就不会被回收
软引用:在内存充足时,是不会GC这个对象的。只有在JVM内存不足的时候才会调用垃圾回收器回收掉这个对象
弱引用:弱引用所引用的对象只能生存到下次GC之前,当发生GC的时候,无论当前内存是否足够,弱引用所引用的对象都会被回收掉。它是和强引用一起配合使用,用来解决内存泄漏问题,比如我们今天所聊的ThreadLocalMap中的Entry对象,就使用了弱引用
虚引用:虚引用是所有引用中最弱的一种引用,其存在就是为了将关联虚引用的对象在被GC掉之后收到一个通知

基础理解
ThreadLocal是Java所提供的线程本地存储机制,是用来解决Java多线程并发问题的一种途径,通过为每一个线程创建一分共享变量的副本,来保证各个线程之间的变量的访问和修改互不影响

内部原理
Thread类中维护了ThreadLocalMap成员变量
而ThradLocalMap维护了以ThreadLocal为key需要存储数据为value的Entry数组

Entry实际上继承了一个ThreadLocal类型的弱引用,并在其作为key,value为Object类型

内存泄漏问题

ThreadLocal对象是有两个引用的
一个是栈上的ThreadLocal引用
一个是ThreadLocalMap的Entry对象的key对他的引用
假如栈上的ThreadLocal引用已经不再使用了,因为用了弱引用,那么ThreadLocal对象在下次GC时,就会被垃圾回收掉,这样做可以很大程度的避免因为使用ThreadLocal的使用而导致的OOM问题,但是这个问题却无法彻底避免,虽然key是弱引用,但是value却是强引用,而且它的生命周期是和Thread一样的,也就是说只要Thread还在,这个对象就无法被回收,Thread对象长期存在的典型案例就是线程池,在线程池中重复利用线程的时候,就会导致这个引用一直在,导致value一直无法被回收

解决方案
当我们每一个ThreadLocal用完之后,手动调用remove()方法,就可以在下次GC的时候,把Entry清理掉

使用场景
1.使用日期工具类,当用到SimpleDateFormat作为成员变量时,可以使用ThreadLocal保证线程安全
2.全局存储用户信息
3.保证一个线程获取到的数据库连接Connection是同一个
4.Spring框架中也大量使用了ThreadLocal保证线程安全

标签:Java,对象,ThreadLocal,GC,引用,线程
From: https://www.cnblogs.com/zhao-zong-yu-hai/p/18030139

相关文章

  • 多线程系列(七) -ThreadLocal 用法及内存泄露分析
    一、简介在Javaweb项目中,想必很多的同学对ThreadLocal这个类并不陌生,它最常用的应用场景就是用来做对象的跨层传递,避免多次传递,打破层次之间的约束。比如下面这个HttpServletRequest参数传递的简单例子!publicclassRequestLocal{/***线程本地变量*/......
  • ThreadLocal使用
     Thread:Thread类中有两个变量threadLocals和inheritableThreadLocals,两者都是ThreadLocal.ThreadLocalMap类型,默认情况下为null,对应源码为1ThreadLocal.ThreadLocalMapthreadLocals=null;23ThreadLocal.ThreadLocalMapinheritableThreadLocals=null;ritabl......
  • 【JDK】Random 的局限以及ThreadLocalRandom 类原理剖析
    1 前言我们平时使用随机数大家可能会用到 Random,但是它的问题大家知道吗?以及该如何解决呢?这节我们就来看看。2  Random类及其局限性在JDK7之前包括现在,java.util.Random都是使用比较广泛的随机数生成工具类,而且java.lang.Math中的随机数生成也使用的是java.util.......
  • ThreadLocal
    (ThreadLocal)什么是ThreadLocal?ThreadLocal被译为==线程本地变量”类==,在Java的多线程并发执行过程中,为保证多个线程对变量的安全访问,可以将变量放到ThreadLocal类型的对象中,使变量在每个线程中都有独立值,不会出现一个线程读取变量时而被另一个线程修改的现象。ThreadLo......
  • 利用ThreadLocal优化获取用户基本信息
    //测试类packagecom.di.bigevent;importorg.junit.jupiter.api.Test;publicclassThreadLocalTest{@TestpublicvoidtestThreadLocalSetAndGet(){ThreadLocaltl=newThreadLocal();newThread(()->{tl.set("李星......
  • threadlocal 线程本地变量,线程独享
         ......
  • 服了,一个ThreadLocal被问出了花
    分享是最有效的学习方式。博客:https://blog.ktdaddy.com/故事地铁上,小帅无力地倚靠着杆子,脑子里尽是刚才面试官的夺命连环问,“用过TheadLocal么?ThreadLocal是如何解决共享变量访问的安全性的呢?你觉得啥场景下会用到TheadLocal?我们在日常用ThreadLocal的时候需要注意什么?Thr......
  • 使用ThreadLocal
    线程是Java实现多任务的基础,Thread对象代表一个线程,我们可以在代码中调用Thread.currentThread()获取当前线程。例如,打印日志时,可以同时打印出当前线程的名字:  对于多任务,Java标准库提供的线程池可以方便地执行这些任务,同时复用线程。Web应用程序就是典型的多任务应用,每个用......
  • Thread和ThreadLocal、ThreadLocalMap的关系
    ThreadLocal是什么 ThreadLocal官方注释: 翻译过来大致意思是:ThreadLocal可以提供局部变量,通过set和get方法对局部变量进行操作,并且局部变量是每个线程独立的、数据隔离的。ThreadLocal通常作为线程的私有的静态变量,用于和UserId、事务Id相关联。set方法:publicvoidse......
  • java中的ThreadLocal
    1.ThreadLocal的基本使用在Java的多线程并发执行过程中,为了保证多个线程对变量的安全访问,可以将变量放到ThreadLocal类型的对象中,使变量在每个线程中都有独立值,不会出现一个线程读取变量时而被另一个线程修改的现象。ThreadLocal类通常被翻译为线程本地变量类或者线程局部变......