zoukankan      html  css  js  c++  java
  • ThreadLocal

    ThreadLocal数据结构

    JDK8设计是此方案,早期设计是:key存的是thread,以threadLocal为单位。

    JDK8设计的好处:当thread销毁时,tthreadLocalMap也会随之销毁,减少内存的使用。

    内存引用流程图

    什么是ThreadLocal?有什么特性?

    ThreadLocal是线程变量,ThreadLocal中设置的变量属于当前线程,该变量对其它线程而言是隔离的。

    特性:

    并发性:多线程并发场景下使用。传递数据:可以通过ThreadLocal在同一线程的上下文中传递参数。线程隔离:每个线程都是独立的,不相互影响。

    ThreadLocalMap初始化大小、加载因子是多少?

    初始化大小是16,加载因子为2/3。HashMap的加载因子是0.75(加载因子越大,装载的越多,hash冲突的可能性越大,反之装载的越少,hash冲突可能性越小,内存使用率不高)

    ThreadLocal底层的hash算法?

    底层使用斐波那契数(黄金分割数)来实现hash算法。ThreadLocal有属性HASH_INCREMENT(斐波那契数),每当创建一个ThreadLocal对象,它的下一个hashCode就会增长0*61c88647

    ThreadLocalMap如何解决hash冲突?

    ThradLocalMap使用开放地址(线性探测)解决hash冲突,HashMap用链地址法解决冲突。

    开放地址法(线性探测法):ThreadLocalMap根据初始key的哈希值确定元素在table数组中的位置,如果发现这个位置已经被其他key值占用,则利用固定的算法寻找一定步长的下个位置,直到找到能够存放的位置。

    常用解决hash冲突的方法:开放地址法(线性探测法、平法探测法、双散列函数探测法);

                                               链地址法:将所有哈希地址为i的元素构成一个称为同义词的单链表,并将单链表的头指针存在哈希表的第i个单元中,因而查找、删除、插入主要在同义词链中进行,适用于经常插入和删除的情况;

                                               再哈希:同时构造多个不同的哈希函数,第一个冲突使用第二个,以此类推;

     如果使用强引用会怎么样?:

    当使用完threadLocal,threadLocalRef被回首时,因为threadLocalMap的Entry使用了强引用,造成key无法回收。
    如果没有手动删除Entry以及CurrentThread依然运行的前提下,始终有强引用链,导致内存泄漏
     
    为什么使用弱引用?
    当threadLocalRef被回收时,因为是弱引用会将key值进行回收,代码中,get、set、remove方法中会进行判断,如果key为null,会将当前entry删除(get、set,只用下一次调用时才会执行)
     
    如何解决threadLocal的内存泄漏问题?
    1.当使用完threadLocal时,手动调remove方法,删除对应的entry
    2.当threadLocal使用结束时,如果当前thread也随之结束,threadLocalMap自然就会被gc回收,从根源解决了内存泄漏(threadLocalMap是thread的一个属性)

    ThreadLocal的应用场景?

      线程安全:ThreadLocal用于保存每个线程独享对象,为每个线程都创建一个副本,确保线程安全。

      参数传递:ThreadLocal用作每个线程内需要独立保存上下文参数,方便其他方法获取这些上下文。在多层架构中,使用较多。

    ThreadLocal扩容机制?

    当table中Entry的数量size>=threshold*3/4时,需要对table进行2倍扩容。扩容的原因:降低哈希冲突

    强引用、软引用、弱引用、虚引用

    强引用:GC回收时不会强制回收,及时内存溢出也不会进行强制回收。例如:new对象

    软引用:当内存不足时,GC会强制回收。用来描述一些不是必须的对象

    弱引用:GC时无论内存是否充足,都会强制回收

    虚引用:不影响对象的生命周期,在任何时候都可能被GC期回收

    ThredaLocal有那些注意事项?

    不要使用ThreadLocal存储大对象

    注意使用ThreadLocal的remove方法,清理过期数据,否则会产生大量脏数据,内存泄漏等问题

    使用private final static 进行修饰,防止多实例时内存的泄漏问题

     
  • 相关阅读:
    MySQL 中 InnoDB 支持的四种事务隔离级别名称,以及逐 级之间的区别?
    NOW()和 CURRENT_DATE()有什么区别?
    什么是非标准字符串类型?
    列的字符串类型可以是什么?
    实践中如何优化 MySQL ?
    可以使用多少列创建索引?
    数据库中的事务是什么?
    锁的优化策略?
    SQL 注入漏洞产生的原因?如何防止?
    强调事项段、其他事项段、关键审计事项
  • 原文地址:https://www.cnblogs.com/BounceGuo/p/13827583.html
Copyright © 2011-2022 走看看