目录
ThreadLocal提供了线程本地变量,它可以保证访问到的变量属于当前线程,每个线程都保存有一个变量副本,每个线程的变量都不同。ThreadLocal相当于提供了一种线程隔离,将变量与线程相绑定,Threadloca适用于在多线程的情况下,可以实现传递数据,实现线程隔离。
1. Threadlocal基本API
1.New Threadlocal();—创建Threadlocal
2.set 设置当前线程绑定的局部变量
3.get 获取当前线程绑定的局部变量
4.remove() 移除当前线程绑定的变量
2. Threadlocal简单用法
1.New Threadlocal();—创建Threadlocal
2.set 设置当前线程绑定的局部变量
3.get 获取当前线程绑定的局部变量
4.remove() 移除当前线程绑定的变量
public class Test003 {
private static ThreadLocal<String> threadLocal = new ThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
threadLocal.set("this is a demo");
System.out.println("成功设置threadLocal");
});
thread.start();
thread.join();
System.out.println(Thread.currentThread().getName() + "," + threadLocal.get());
}
}
根据子线程 在Threadlocal存放局部变量,但是获取的时候是主线程,所以无法获取。
3. Threadlocal应用场景
- Spring事务模板类
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); - 获取httprequest
HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest(); - Aop调用链传递参数
LCN/seata 生成全局的id
4. Threadlocal与Synchronized区别
Synchronized与Threadlocal 都可以实现多线程访问,保证线程安全的问题。
A. Synchronized采用当多个线程竞争到同一个资源的时候,最终只能够有一个线程访问,采用时间换空间的方式,保证线程安全问题
B.Threadlocal在每个线程中都自己独立的局部变量, 空间换时间,相互之间都是隔离,相比来说Threadlocal效率比Synchronized效率更高。
5. Threadlocal真实应用场景
例如:在aop中生成全局的id,目标方法获取aop中生成的全局id;
Aop拦截目标方法 生成全局的id
@Aspect
@Component
@Slf4j
public class DemoAop {
@Autowired
private GlobalIDContextholder globalIDContextholder;
/**
* 切入点
*/
@Pointcut("execution(public * com.demo.service.*Service.*(..))")
public void log() {
}
/**
* 前置操作
*
* @param point 切入点
*/
@Before("log()")
public void beforeLog(JoinPoint point) {
UUID globalId = UUID.randomUUID();
globalIDContextholder.set(globalId.toString());
}
}
@RestController
public class DemoService {
@Autowired
private GlobalIDContextholder globalIDContextholder;
@GetMapping("/doDemo")
public String doDemo() {
return "从aop中获取的全局id:" + globalIDContextholder.getId();
}
}
@Component
public class GlobalIDContextholder {
private ThreadLocal<String> globalIds = new ThreadLocal<String>();
public String getId() {
return globalIds.get();
}
public void set(String globalId) {
globalIds.set(globalId);
}
}
6. 什么是内存溢出
指程序在申请内存时,没有足够的内存空间提供其使用,出现 out of memory。 OOM溢出,一般解决办法:加内存。
eg:堆内存 1gb 申请内存2gb
7. 什么是内存泄漏
指程序在申请内存后,无法释放已申请的内存空间,内存泄露会导致内存被占光,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
8. 强、软、弱、虚引用实现区别
-
强引用: 当内存不足时,JVM开始进行GC(垃圾回收),对于强引用对象,就算是出现了OOM也不会对该对象进行回收,死都不会收。
-
软引用:当系统内存充足的时候,不会被回收;当系统内存不足时,它会被回收,软引用通常用在对内存敏感的程序中,比如高速缓存就用到软引用,内存够用时就保留,不够时就回收。
软引用对象它是在申请堆内存不足时,才会触发清理软引用对象; -
弱引用:弱引用需要用到java.lang.ref.WeakReference类来实现,它比软引用的生存周期更短。对于只有弱引用的对象来说,只要有垃圾回收,不管JVM的内存空间够不够用,都会回收该对象占用的内存空间。
-
虚引用:虚引用需要java.lang.ref.Phantomreference类来实现。顾名思义,虚引用就是形同虚设。与其它几种引用不同,虚引用并不会决定对象的生命周期。所以, 虚引用通常用来跟踪对象被垃圾回收的活动。
比如,虚引用可用于在某些对象超出范围以执行某些资源清理时通知您。
9. Threadlocal原理分析
- 在每个线程中都有自己独立的ThreadLocalMap对象,中Entry对象。
- 如果当前线程对应的的ThreadLocalMap对象为空的情况下,则创建该ThreadLocalMap对象,并且赋值键值对。 Key 为 当前new ThreadLocal对象,value 就是为object变量值。
Set方法
- 获取到当前的线程
- 获取到当前线程中的threadLocals
- threadLocals类型ThreadLocalMap 底层基于Entry对象封装
- Entry对象 key=ThreadLocal value缓存的变量的值
- 一个线程对应一个独立ThreadLocalMap 一个ThreadLocalMap k==ThreadLocal value缓存变量的值
Get方法实现: - 获取当前线程对应的threadLocals
- 在根据具体threadLocal对象获取value值
10. Threadlocal产生内存泄漏问题
1.因为每个线程中都有自己独立的ThreadLocalMap对象,key为ThreadLocal,value 是为变量值。
2.Key为ThreadLocal 作为Entry对象的key,是弱引用,当ThreadLocal指向null的时候,Entry对象中的key变为null,该对象一直无法被垃圾收集机制回收,一直占用到了系统内存,有可能会发生内存泄漏的问题。
11. 如何避免Threadlocal内存泄漏问题
- 可以自己调用remove方法将不要的数据移除避免内存泄漏的问题;
- 每次在做set方法的时候会清除之前 key为null;
- Threadlocal为弱引用
12. Threadlocal采用弱引用而不是强引用
如果key是为强引用: 当我们现在将ThreadLocal 的引用指向为null,但是
每个线程中有自己独立ThreadLocalMap还一直在继续持有该对象,但是我们
ThreadLocal 对象不会被回收,就会发生ThreadLocal内存泄漏的问题。
如果key是为弱引用:
当我们现在将ThreadLocal 的引用指向为null,GC触发回收垃圾的情况下,Entry 中的key指向为null,但是下次调用set方法的时候,会根据判断如果key空的情况下,直接删除,有可能会发生Entry 发生内存泄漏的问题。
不管是用强引用还是弱引用都是会发生内存泄漏的问题。
弱引用中不会发生ThreadLocal内存泄漏的问题。
但是最终根本的原因Threadlocal内存泄漏的问题,产生于ThreadLocalMap与
我们当前线程的生命周期一样,如果没有手动的删除的情况下,就有可能会发生内存泄漏的问题。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/131209.html