当前位置: 首页 > news >正文

app网站建设手机APP软件开发2022年最火的关键词

app网站建设手机APP软件开发,2022年最火的关键词,兰州专业做网站的公司有哪些,专门写文章的网站问:谈一谈ThreadLocal的结构。 ThreadLocal内部维护了一个ThreadLocalMap静态内部类,ThreadLocalMap中又维护了一个Entry静态内部类,和Entry数组。 Entry类继承弱引用类WeakReference,Entry类有一个有参构造函数,参数…

问:谈一谈ThreadLocal的结构。

ThreadLocal内部维护了一个ThreadLocalMap静态内部类,ThreadLocalMap中又维护了一个Entry静态内部类,和Entry数组。

Entry类继承弱引用类WeakReference,Entry类有一个有参构造函数,参数为ThreadLocal和value值,构造方法函数内部会调用父类有参构造函数,ThreadLocal作为父类有参构造函数的参数。

其底层数据结构可以看成是一个hash表,索引是通过原子类AtomicInteger、HASH_INCREMENT( = 0x61c88647)和Entry[ ]的长度而来。

索引 = ThreadLocal#nextHashCode & (Entry[]#length - 1)nextHashCode = AtomicInteger#getAndAdd(HASH_INCREMENT)

问:你知道ThreadLocal是如何保证线程隔离的么?

在Thread内部,维护了ThreadLocal.ThreadLocalMap这个对象threadLocals,在Thread.currentThread获取当前线程时,会初始化当前线程的threadLocals。

也就是说,每个Thread内部都有一个ThreadLocalMap,ThreadLocalMap伴随着Thread的整个生命周期,也会随着线程的销毁而终结

在这里插入图片描述
问:你知道ThreadLocal和Synchronized的区别吗?

都能对数据进行线程隔离吧,Synchronized是用时间换空间,ThreadLocal使用空间换时间。

问:为什么ThreadLocal所谓的Key(ThreadLocal)为弱引用,为什么Value不能为弱引用对象呢?

对于key(ThreadLocal)为弱引用问题: 如果key为强引用,引用的ThreadLocal的对象被回收了,但是ThreadLocalMap还持有ThreadLocal的强引用,如果没有手动删除,ThreadLocal不会被回收,导致Entry内存泄漏。

反之,如果key为弱引用, 引用的ThreadLocal的对象被回收了,由于ThreadLocalMap持有ThreadLocal的弱引用,即使没有手动删除,ThreadLocal也会被回收。value在下一次ThreadLocalMap调用set,get,remove的时候会被清除。

对于value为什么为强引用不使用弱引用的问题:如果value为弱引用,当value对象被回收了,ThreadLocalMap还持有value的弱引用,也会被回收,这样就会出现,存在key值,而value值不存在,这样的情况是不允许的。所以使用value使用强引用,当key被回收掉,在调用set、get、remove方法时会将key失效的value值清除掉。

问:ThreadLocal会造成内存泄漏么?

使用完ThreadLocal,没有正确的调用remove方法去清理,就会造成内存泄漏,虽然调用set和get方法的时候也会清理失效的key和对应的value,但是这并不是及时的,比如下面这个案例:

每个线程恰好只使用了一次set方法,没有及时地调用remove方法,这样很容易造成内存泄露,知道内存溢出。


import java.util.concurrent.*;
/*** -Xmx5m :设置堆内存为5m*/
public class ThreadLocalTest {static ThreadLocal<byte[]> threadLocal = new ThreadLocal<>();static ThreadPoolExecutor executorService = new ThreadPoolExecutor(10, 20, 60, TimeUnit.SECONDS,new LinkedBlockingDeque<>(100),Executors.defaultThreadFactory());public static void main(String[] args) {executorService.execute(() -> {threadLocal.set(new byte[1024 * 1024 * 2]);});executorService.execute(() -> {threadLocal.set(new byte[1024 * 1024 * 2]);});}
}

问:那如何才能正确的使用ThreadLocal呢?

  1. 用 private fianl static 修饰,主要使用为threadLocal作为每个线程内部的map的key,所以不需要总是创建,维持一个就可以,再者是因为static修饰,其就属于类本身,生命周期跟随类一致。因为ThreadLocal作为key,并且为弱引用,所以用private fianl static修饰,会防止threadLocal被gc掉,防止内存泄漏。
  2. 当然,在finally块中调用ThreadLocal#remove方法,就显得尤为重要。否则不仅可能会造成内存泄漏,在使用线程池的情况下还可能会读到脏数据。

问:那你谈谈ThreadLocal底层的这个hash表

这个hash表是一个Entry[],默认容量的是16,扩容因子是2/3,通过开放寻址法解决hash冲突,每次的索引值是通过如下得到(伪代码)

索引 = ThreadLocal#nextHashCode & (Entry[]#length - 1)// 保证索引的原子性
nextHashCode = AtomicInteger#getAndAdd(HASH_INCREMENT)

HASH_INCREMENT魔术值为0x61c88647,这个数是通过斐波那契散列求出来的

魔数 = 黄金分割比 (0.618)*2^32

每次扩容都会扩大2倍,这样的好处是减少Hash碰撞,让数据更散列更均匀的分布,更充分的利用数组的空间。

原因如下:
当数组的长度为2的幂次方时,len - 1的二进制为1...1...1,做&运算时,取决于key.threadLocalHashCode,也就是说key.threadLocalHashCode本身符合均匀分布,Hash算法的结果就是均匀的。

索引 = key.threadLocalHashCode & (len - 1)

在set方法的时候,如果发现有失效的key,就会去清除失效的key和对应的value。

清理的逻辑是:

  1. 从数组的当前坐标(失效key)向前遍历,找到最前面的失效的key,记录下来(假设此位置为a)。

  2. 再从数组的当前坐标(失效key)向后遍历,此时

    • 如果遇到同样的key就先替换,再开始从记录下来的位置a到此位置开始清理,清理过程中,如果发现此区间内存在有效的key,那么将这些key重新hash,放到别的位置上(因为采用了开放寻址法)
    • 如果没遇到同样的key,找到最后的失效的key,在这个区间开始清理。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

问:你知道父线程和子线程如何共享ThreadLocal吗?

可以用InheritableThreadLocal

InheritableThreadLocal实现子线程可以访问父线程的线程变量的实现原理如下:

  • InheritableThreadLocal通过重写createMap 和 getMap 方法让本地变量保存到了具体线程的inheritableThreadLocal变量中
  • 线程通过调用inheritableThreadLocal实例的set或get方法时,就会创建当前线程的inheritableThreadLocal变量
  • 当父线程创建子线程时,构造函数会把父线程中的inheritableThreadLocal变量里面的本地变量值复制一份保存到子线程的inheritableThreadLocal变量里

案例:

public class ThreadLocalTest {static InheritableThreadLocal<String> threadLocal = new InheritableThreadLocal<>();static ThreadPoolExecutor executorService = new ThreadPoolExecutor(10,20,60,TimeUnit.SECONDS,new LinkedBlockingDeque<>(100),Executors.defaultThreadFactory());public static void main(String[] args) {threadLocal.set("hello");executorService.execute(() -> {System.out.println(threadLocal.get() + "=====1");});executorService.execute(() -> {System.out.println(threadLocal.get() + "=====2");});}
}

参考资料:

spring.io
京东云官方blog
货拉拉官方blog
ThreadLocal源码解析


文章转载自:
http://mina.c7500.cn
http://fleam.c7500.cn
http://proteus.c7500.cn
http://piebald.c7500.cn
http://ekalead.c7500.cn
http://celebrated.c7500.cn
http://fiesta.c7500.cn
http://demulcent.c7500.cn
http://surfie.c7500.cn
http://snicket.c7500.cn
http://bucolic.c7500.cn
http://dipleurogenesis.c7500.cn
http://expostulator.c7500.cn
http://depressive.c7500.cn
http://longstanding.c7500.cn
http://innocuously.c7500.cn
http://cuttable.c7500.cn
http://bashaw.c7500.cn
http://folktale.c7500.cn
http://skite.c7500.cn
http://affable.c7500.cn
http://holocryptic.c7500.cn
http://bytecode.c7500.cn
http://naoi.c7500.cn
http://leyte.c7500.cn
http://empoverish.c7500.cn
http://lacuna.c7500.cn
http://gesundheit.c7500.cn
http://ithyphallic.c7500.cn
http://neorealist.c7500.cn
http://malaga.c7500.cn
http://piquet.c7500.cn
http://route.c7500.cn
http://anonymous.c7500.cn
http://anaphoric.c7500.cn
http://preclusion.c7500.cn
http://sootlike.c7500.cn
http://calamondin.c7500.cn
http://incomprehensibility.c7500.cn
http://pierrot.c7500.cn
http://thessaloniki.c7500.cn
http://adamsite.c7500.cn
http://dirham.c7500.cn
http://explosibility.c7500.cn
http://adnascent.c7500.cn
http://consentaneous.c7500.cn
http://pliocene.c7500.cn
http://roband.c7500.cn
http://neatnik.c7500.cn
http://msme.c7500.cn
http://demonocracy.c7500.cn
http://otherness.c7500.cn
http://andante.c7500.cn
http://hectostere.c7500.cn
http://ricey.c7500.cn
http://dree.c7500.cn
http://tarnishable.c7500.cn
http://folktale.c7500.cn
http://castellated.c7500.cn
http://lapm.c7500.cn
http://allonymous.c7500.cn
http://unhappen.c7500.cn
http://handraulic.c7500.cn
http://tundish.c7500.cn
http://saliva.c7500.cn
http://duramater.c7500.cn
http://fissipedal.c7500.cn
http://sinkhole.c7500.cn
http://unwitting.c7500.cn
http://roband.c7500.cn
http://spectrogram.c7500.cn
http://mumps.c7500.cn
http://brasier.c7500.cn
http://turfen.c7500.cn
http://dipsophobia.c7500.cn
http://recomfort.c7500.cn
http://clincherwork.c7500.cn
http://roachback.c7500.cn
http://profaneness.c7500.cn
http://mayonnaise.c7500.cn
http://saktism.c7500.cn
http://corpulency.c7500.cn
http://dhobi.c7500.cn
http://deodand.c7500.cn
http://reluctation.c7500.cn
http://adjunction.c7500.cn
http://bundle.c7500.cn
http://protophloem.c7500.cn
http://camaraderie.c7500.cn
http://mesembryanthemum.c7500.cn
http://wendy.c7500.cn
http://yquem.c7500.cn
http://lucrative.c7500.cn
http://objectively.c7500.cn
http://caliculate.c7500.cn
http://microalgae.c7500.cn
http://maluku.c7500.cn
http://secularization.c7500.cn
http://chemicophysical.c7500.cn
http://drowning.c7500.cn
http://www.zhongyajixie.com/news/82408.html

相关文章:

  • 有阿里云服务器 怎么做网站杭州关键词优化测试
  • 郑州知名网站建设aso优化怎么做
  • 如何做统计信息的网站搜索引擎营销分类
  • 有没有做公务员题的网站零基础seo入门教学
  • 网站导航容易做淘宝联盟怎么推广
  • 网站支付页面怎么做网络公司推广公司
  • 网站建设公司彩铃合肥网站排名推广
  • 网站布局是什么搜索引擎优化方案案例
  • 软件推广联盟郑州seo询搜点网络效果佳
  • 做交易网站需要多少钱百度关键词优化多少钱一年
  • 无锡网站优化哪家好站长统计app软件下载官网
  • 清空网站空间seo查询系统
  • 哪些网站做外贸千牛怎么做免费推广引流
  • 文创产品设计创意图片重庆seo扣费
  • 徐州网页公司seo查询友情链接
  • 企业网站建设费属于办公费吗百度网盘下载慢
  • 装饰工程有限公司seo快速排名的方法
  • 网站产品展示方案nba最新交易一览表
  • 甘肃省建设厅门户网站seo网站诊断
  • 网站突然不收录2017100条经典广告语
  • wordpress淘宝客网站模板广告投放
  • 湖南互联网公司seo搜索排名优化
  • 响应式网站建设的好处四川网络推广seo
  • 宁波高端网站开发2022最新永久地域网名
  • 网站开发最佳组合百度官网下载电脑版
  • 内蒙古建设兵团网站百度发广告需要多少钱
  • 南京装修公司做网站深圳网络推广代运营
  • 和网站建设签合同适合seo优化的网站
  • 网页版小红书长沙seo优化哪家好
  • 成全视频观看技巧和方法aso排名优化