=Start=
缘由:
前段时间在用Java进行加解密的时候碰到了一个线程安全的问题,后来发现是因为对Java的Cipher包不熟悉导致,最后通过ThreadLocal的方式在正确性和性能上取得了一个平衡。
虽然问题是解决了,但是ThreadLocal是什么,以及为什么能解决这个问题我还不是特别清楚,所以就想专门学习一下ThreadLocal的相关知识,因为整体不算复杂,所以在收集、整理的过程中也就完成了相关知识的学习和介绍。
正文:
参考解答:
# ThreadLocal 是什么?
ThreadLocal是一个关于创建线程局部变量的类。ThreadLocal,很多地方叫做线程本地变量,也有些地方叫做线程本地存储,其实意思差不多。可能很多朋友都知道ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。
通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。而使用ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改。
如何验证 threadLocal 确实是每个线程都创建了一个各自的副本?
public class ThreadLocalTest { ThreadLocal<Long> longLocal = new ThreadLocal<Long>(); ThreadLocal<String> stringLocal = new ThreadLocal<String>(); public void set() { longLocal.set(Thread.currentThread().getId()); stringLocal.set(Thread.currentThread().getName()); } public long getLong() { return longLocal.get(); } public String getString() { return stringLocal.get(); } public static void main(String[] args) throws InterruptedException { final ThreadLocalTest threadLocalTest = new ThreadLocalTest(); threadLocalTest.set(); System.out.println(threadLocalTest.getLong()); System.out.println(threadLocalTest.getString()); Thread thread1 = new Thread(){ public void run() { threadLocalTest.set(); System.out.println(threadLocalTest.getLong()); System.out.println(threadLocalTest.getString()); }; }; thread1.start(); thread1.join(); System.out.println(threadLocalTest.getLong()); System.out.println(threadLocalTest.getString()); } }
# threadLocal 何时用?怎么用?
- 最常见的ThreadLocal使用场景是用来解决数据库连接、Session管理等问题。
- 还有就是密码算法中的 init 初始化操作,因为Java中的Cipher不是线程安全的,但是 init 又非常慢,所以比较适合。
# threadLocal 使用的注意事项?
1、先 set 再 get 否则可能会出异常,或者通过重写 initialValue 方法来避免此问题;
参考链接:
- Java并发编程:深入剖析ThreadLocal
- 理解Java中的ThreadLocal
- Java进阶(七)正确理解Thread Local的原理与适用场景
http://www.jasongj.com/java/threadlocal/ - Java ThreadLocal的使用
- 深入理解 Java 之 ThreadLocal 工作原理
=END=
《 “Java中的ThreadLocal学习理解” 》 有 3 条评论
ThreadLocal:Java中的影分身
https://mp.weixin.qq.com/s/OzzAGVpFXCdVQyNmzLnNEw
`
希望可以通过这篇学习笔记来解决这几个问题:
ThreadLocal是用来解决什么问题的?
如何使用ThreadLocal?
ThreadLocal的实现原理是什么?
可否举几个实际项目中使用ThreadLocal的案例?
`
手撕面试题ThreadLocal!!!
https://mp.weixin.qq.com/s/8Ql-5kaUtxiCWyHR6uPPBw
`
ThreadLocal用在什么地方?
如果仅仅就一个线程,那么都不用谈ThreadLocal的,ThreadLocal是用在多线程的场景的!
ThreadLocal归纳下来就2类用途:
1、保存线程上下文信息,在任意需要的地方可以获取!!!
2、线程安全的,避免某些情况需要考虑线程安全必须同步带来的性能损失!!!
ThreadLocal一些细节!
Thread类有属性变量threadLocals (类型是ThreadLocal.ThreadLocalMap),也就是说每个线程有一个自己的ThreadLocalMap ,所以每个线程往这个ThreadLocal中读写隔离的,并且是互相不会影响的。
一个ThreadLocal只能存储一个Object对象,如果需要存储多个Object对象那么就需要多个ThreadLocal!!!
ThreadLocal的最佳实践!
由于线程的生命周期很长,如果我们往ThreadLocal里面set了很大很大的Object对象,虽然set、get等等方法在特定的条件会调用进行额外的清理,但是ThreadLocal被垃圾回收后,在ThreadLocalMap里对应的Entry的键值会变成null,但是后续在也没有操作set、get等方法了。
所以最佳实践,应该在我们不使用的时候,主动调用remove方法进行清理。
`
惊:FastThreadLocal吞吐量居然是ThreadLocal的3倍!!!
https://mp.weixin.qq.com/s/xJSmSexl8mzdX8ivSRAb6Q
`
关于FastThreadLocal,零度准备从这几个方面进行讲解:
– FastThreadLocal的使用。
– FastThreadLocal并不是什么情况都快,你要用对才会快。
– FastThreadLocal利用字节填充来解决伪共享问题。
– FastThreadLocal比ThreadLocal快,并不是空间换时间。
– FastThreadLocal不在使用ObjectCleaner处理泄漏,必要的时候建议重写onRemoval方法。
– FastThreadLocal为什么快?
`