当前位置:首页 > 技术 >

threadlocal为什么是弱引用(threadlocal为什么是安全的)

来源:原点资讯(m.360kss.com)时间:2023-04-15 23:32:30作者:YD166手机阅读>>

前言

大家好,我是捡田螺的小男孩

无论是工作还是面试,我们都会跟ThreadLocal打交道,今天就跟大家聊聊ThreadLocal哈~

  1. ThreadLocal是什么?为什么要使用ThreadLocal
  2. 一个ThreadLocal的使用案例
  3. ThreadLocal的原理
  4. 为什么不直接用线程id作为ThreadLocalMap的key
  5. 为什么会导致内存泄漏呢?是因为弱引用吗?
  6. Key为什么要设计成弱引用呢?强引用不行?
  7. InheritableThreadLocal保证父子线程间的共享数据
  8. ThreadLocal的应用场景和使用注意点
  • github地址,麻烦给个star鼓励一下,感谢感谢
  • 公众号:捡田螺的小男孩(欢迎关注,干货多多)
1. ThreadLocal是什么?为什么要使用ThreadLocal?

ThreadLocal是什么?

ThreadLocal,即线程本地变量。如果你创建了一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的一个本地拷贝,多个线程操作这个变量的时候,实际是在操作自己本地内存里面的变量,从而起到线程隔离的作用,避免了并发场景下的线程安全问题。

//创建一个ThreadLocal变量 static ThreadLocal<String> localVariable = new ThreadLocal<>(); 复制代码

为什么要使用ThreadLocal

并发场景下,会存在多个线程同时修改一个共享变量的场景。这就可能会出现线性安全问题

为了解决线性安全问题,可以用加锁的方式,比如使用synchronized 或者Lock。但是加锁的方式,可能会导致系统变慢。加锁示意图如下:

threadlocal为什么是弱引用,threadlocal为什么是安全的(1)

还有另外一种方案,就是使用空间换时间的方式,即使用ThreadLocal。使用threadLocal类访问共享变量时,会在每个线程的本地,都保存一份共享变量的拷贝副本。多线程对共享变量修改时,实际上操作的是这个变量副本,从而保证线性安全。

threadlocal为什么是弱引用,threadlocal为什么是安全的(2)

2. 一个threadLocal的使用案例

日常开发中,ThreadLocal经常在日期转换工具类中出现,我们先来看个反例

/** * 日期工具类 */ public class DateUtil { private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public static Date parse(String dateString) { Date date = null; try { date = simpleDateFormat.parse(dateString); } catch (ParseException e) { e.printStackTrace(); } return date; } } 复制代码

我们在多线程环境跑DateUtil这个工具类:

public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(10); for (int i = 0; i < 10; i ) { executorService.execute(()->{ System.out.println(DateUtil.parse("2022-07-24 16:34:30")); }); } executorService.shutdown(); } 复制代码

运行后,发现报错了:

threadlocal为什么是弱引用,threadlocal为什么是安全的(3)

如果在DateUtil工具类,加上ThreadLocal,运行则不会有这个问题:

/** * 日期工具类 */ public class DateUtil { private static ThreadLocal<SimpleDateFormat> dateFormatThreadLocal = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); public static Date parse(String dateString) { Date date = null; try { date = dateFormatThreadLocal.get().parse(dateString); } catch (ParseException e) { e.printStackTrace(); } return date; } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(10); for (int i = 0; i < 10; i ) { executorService.execute(()->{ System.out.println(DateUtil.parse("2022-07-24 16:34:30")); }); } executorService.shutdown(); } } 复制代码

运行结果:

Sun Jul 24 16:34:30 GMT 08:00 2022 Sun Jul 24 16:34:30 GMT 08:00 2022 Sun Jul 24 16:34:30 GMT 08:00 2022 Sun Jul 24 16:34:30 GMT 08:00 2022 Sun Jul 24 16:34:30 GMT 08:00 2022 Sun Jul 24 16:34:30 GMT 08:00 2022 Sun Jul 24 16:34:30 GMT 08:00 2022 Sun Jul 24 16:34:30 GMT 08:00 2022 Sun Jul 24 16:34:30 GMT 08:00 2022 Sun Jul 24 16:34:30 GMT 08:00 2022 复制代码

刚刚反例中,为什么会报错呢?这是因为SimpleDateFormat不是线性安全的,它以共享变量出现时,并发多线程场景下即会报错。

为什么加了ThreadLocal就不会有问题呢?并发场景下,ThreadLocal是如何保证的呢?我们接下来看看ThreadLocal的核心原理。

3. ThreadLocal的原理3.1 ThreadLocal的内存结构图

为了有个宏观的认识,我们先来看下ThreadLocal的内存结构图

threadlocal为什么是弱引用,threadlocal为什么是安全的(4)

首页 123下一页

栏目热文

threadlocal使用实例(threadlocal例子)

threadlocal使用实例(threadlocal例子)

如何统计时间说着说着,慧能写了一段程序说着说着一尘就随手写了一段程序经验丰富的慧能一眼就看出来这个程序的致命缺陷这个程序...

2023-04-15 23:18:30查看全文 >>

threadlocal的缺点(threadlocal应用场景)

threadlocal的缺点(threadlocal应用场景)

在 Java 中,如果要问哪个类使用简单,但用好最不简单?我想你的脑海中一定会浮现出一次词——“ThreadLocal”...

2023-04-15 23:39:40查看全文 >>

threadlocal正确使用方法(thread local通俗易懂)

threadlocal正确使用方法(thread local通俗易懂)

开场白张三最近天气很热心情不是很好,所以他决定出去面试跟面试官聊聊天排解一下,结果刚投递简历就有人约了面试。我丢,什么情...

2023-04-15 23:31:07查看全文 >>

threadlocal为什么要加static(threadlocalentry为什么是弱引用)

threadlocal为什么要加static(threadlocalentry为什么是弱引用)

原文地址:https://mp.weixin.qq.com/s/SysYihctu03RlUtI0pcG7w作者:零度冰...

2023-04-15 23:48:12查看全文 >>

通体大理石瓷砖要除蜡吗

通体大理石瓷砖要除蜡吗

    说到大理石石材,大家都不陌生,那么讲到大理石石材的抛光打蜡的问题,这个很多大家可能就不是很特别的清楚了,大理石石...

2023-04-15 23:58:01查看全文 >>

threadlocal使用场景(threadlocal不能使用的场景)

threadlocal使用场景(threadlocal不能使用的场景)

推荐学习 前言相信很多同学都听过threadLocal,即使没用过也听过。但是要仔细一问ThreadLocal是个啥,...

2023-04-15 23:59:17查看全文 >>

threadlocal用法示例(threadlocal使用场景)

threadlocal用法示例(threadlocal使用场景)

1.ThreadLocal的使用场景1.1 场景1每个线程需要一个独享对象(通常是工具类,典型需要使用的类有Simple...

2023-04-15 23:54:10查看全文 >>

threadlocal底层原理(ThreadLocal原理)

threadlocal底层原理(ThreadLocal原理)

引言这是JWT认证条件下的getCurrentLoginUser代码实现,请分析性能:在生产环境中,currentLog...

2023-04-15 23:51:07查看全文 >>

threadlocal 使用场景(threadlocal详细介绍)

threadlocal 使用场景(threadlocal详细介绍)

两大使用场景-ThreadLocal的用途典型场景1: 每个线程需要一个独享的对象(通常是工具类,典型需要使用的类有Si...

2023-04-15 23:45:51查看全文 >>

threadlocal实例(threadlocal使用范例)

threadlocal实例(threadlocal使用范例)

作者:@adamhandzybuluo.com/adamhand/note/1370920ThreadLocal是什么首...

2023-04-15 23:56:45查看全文 >>

文档排行