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

云南大学网站建设英文外链代发

云南大学网站建设,英文外链代发,南京营销型网站制作,网站建设申请关键点总结: ThreadLocal更像是对其他类型变量的一层包装,通过ThreadLocal的包装使得该变量可以在线程之间隔离和当前线程全局共享。在Thread中有一个threadLocals变量,类型为ThreadLocal.ThreadLocalMap,ThreadLocalMap中key是Th…

关键点总结:

  • ThreadLocal更像是对其他类型变量的一层包装,通过ThreadLocal的包装使得该变量可以在线程之间隔离当前线程全局共享
  • Thread中有一个threadLocals变量,类型为ThreadLocal.ThreadLocalMapThreadLocalMapkeyThreadLocal,value是存入的变量值。
  • ThreadthreadLocalsThreadLocal维护。
  • 每个线程的本地变量不是存储在ThreadLocal示例里边的,而是存放在调用线程的threadLocals变量里边。
  • LoreadLocal类型的本地变量存放在具体的线程内存空间中。ThreadLocal就是一个工具,通过set方法把value值放入调用线程的threadLocals变量。调用**get**方法再从当前线程的threadLocals中拿出数据。
  • 如果调用线程一直不终止,那么这个本地变量会一直存放在调用线程的thradLocals变量里边,所以当不需要使用本地变量的时候可以通过调用ThreadLocalremove方法删除本地变量
  • Java中的内存泄露的情况:长生命周期的对象持有短生命周期的对象的引用就很有可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是Java中内存泄露发生的场景。

📚概述

ThreadLocal:线程本地变量,用于解决多线程并发访问时共享变量的问题。**

📗ThreadLocal实现原理

📐存储原理

  • Thread中有一个threadLocals变量,类型为ThreadLocal.ThreadLocalMapThreadLocalMapkeyThreadLocal,value是存入的变量值。
  • ThreadthreadLocalsThreadLocal维护。
  • 每个线程的本地变量不是存储在ThreadLocal示例里边的,而是存放在调用线程的threadLocals变量里边。
  • LoreadLocal类型的本地变量存放在具体的线程内存空间中。ThreadLocal就是一个工具,通过set方法把value值放入调用线程的threadLocals变量。调用**get**方法再从当前线程的threadLocals中拿出数据。
  • 如果调用线程一直不终止,那么这个本地变量会一直存放在调用线程的thradLocals变量里边,所以当不需要使用本地变量的时候可以通过调用ThreadLocalremove方法删除本地变量

💡ThreadLocal常用方法

  • set(T value):设置线程本地变量的内容。
  • get():获取线程本地变量的内容。
  • remove():移除线程本地变量。注意在线程池的线程复用场景中在线程执行完毕时一定要调用remove,避免在线程被重新放入线程池中时被本地变量的旧状态仍然被保存。

Question1:为什么get()remove()方法没有入参?

Question2ThreadLocal对象作为key存在Thread中,实际中一个线程可能会经过很多方法,如何从Thread中获取到ThreadLocal的数据呢?threadlocal如何使用(没有ThreadLocal时,Thread能获取到存储的数据吗)?

ThreadLocal#set(T value)方法:

public void set(T value) {// 获取当前线程Thread t = Thread.currentThread();// 获取从当前线程中获取ThreadlocalMap,如果不为空存入值(key为当前threadlocal对象实例,value为值),为空则创建一个ThreadLocaMap,key是当前的ThreadLocal ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);
}// 从Thread中获取ThreadLocalMap
ThreadLocalMap getMap(Thread t) {return t.threadLocals;
}
// 创建ThreadLocalMap 并赋值给Thread的threadLocals属性
void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue);
}

ThreadLocal#get()方法:

// 以当前ThreadLocal对象为key从Map中获取数据,数据不为空直接返回数据,数据为空,则创建一个key是当前ThreadLocal、value为null的数据存入Map中,并返回null
public T get() {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {ThreadLocalMap.Entry e = map.getEntry(this);if (e != null) {@SuppressWarnings("unchecked")T result = (T)e.value;return result;}}return setInitialValue();
}
// 创建一个可以是当前ThreadLocal、value为null的数据存入Map中
private T setInitialValue() {T value = initialValue();Thread t = Thread.currentThread();// 获取线程中的threadLocals变量ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);return value;
}protected T initialValue() {return null;
}

ThreadLocal#remove()方法:

// 从map中移除当前ThreadLocal为key的数据
public void remove() {ThreadLocalMap m = getMap(Thread.currentThread());if (m != null)m.remove(this);}

总结:
如下图所示,在每个线程内部都有一个名为 threadLocals 的成员变量,该变量的类型为 ThreadLocalMap,其中 key 为我们定义的 ThreadLocal变量的 this 引用,value 则为我门使用 set方法设置的值。每个线程的本地变量存放在线程自己的内存变量threadLocals 中,如果当前线程一直不消亡,那么这些本地变量会一直存在,所以可能会造成内存溢出,因此使用完毕后要记得调用 ThreadLocalremove 方法删除对应线程的 threadLocals 中的本地变量。

📐使用说明

多个Thread与一个ThreadLocal

代码示例:

ThreadLocal<String> content = new ThreadLocal<>();// 线程1
Thread thread = new Thread(() -> {content.set("数据A");System.out.println(Thread.currentThread().getName() +":"+ content.get());
}, "线程1");
thread.start();// 线程2
Thread thread2 = new Thread(() -> {content.set("数据B");System.out.println(Thread.currentThread().getName() +":"+ content.get());}, "线程2");
thread2.start();

输出结果:

线程1:数据A
线程2:数据B

为什么多个线程访问同一个ThreadLocal时,数据不会乱呢,也就是Thread2中不会获取到Thread1中存储的数据?
本质还是因为跟前边给出的存储原理图有关,同一个key,数据存储在不同的Thread中,在不同的Thread中访问,肯定不会访问到其他Thread的数据

同一个Thread与多个ThreadLocal

本质上是一致的,我们只需要记住,真实数据是存放在**Thread****threadLocals**变量中的即可,各个**Thread**中数据互不干扰
多个ThreadLocal时,仅仅是增加了Thread**threadLocals**键值对的数量。

ThreadLocal local1 = new ThreadLocal();
threadLocal.set("数据1");ThreadLocal local2 = new ThreadLocal();
threadLocal2.set("数据2");

💡ThreadLocal使用不当导致内存泄露

内存泄露问题:指程序中动态分配的堆内存由于某种原因没有被释放或者无法释放,造成系统内存的浪费,导致程序运行速度减慢或者系统奔溃等严重后果。内存泄露堆积将会导致内存溢出。

ThreadLocalTreadLocalMapEntry继承了WeakReference
当一个对象被WeakReference包装后,它就产生了一个弱引用指向它。此时即使把强引用切断,仍然有弱引用连接着。但是由于弱引用的特性,这个对象会在下次被GC线程被直接回收。
本质不是**Entry**是弱应用而是**Entry****key**为弱引用。
image.png

使用弱引用的原因

强引用情况:
theadlocalnull被回收时,Thread还存在的情况下,依然存在到达ThreadLocal对象的引用链(ThreadLocalMap中的key),无法清除ThreadLocal的内容,同时ThreadLocalMap中的Value也会保留。在使用线程池的情况下(Thread可能一直存在)可能会出现内存泄露。

弱应用情况:

theadlocalnull被回收时,Thread还存在的情况下,在下次GC时就会将ThreadLocal对象清除,但是ThreadLocalMap中的Value还会保留,导致无法删除。在使用线程池的情况下(Thread可能一直存在)可能会出现内存泄露。

Java中的内存泄露的情况:长生命周期的对象持有短生命周期的对象的引用就很有可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是Java中内存泄露发生的场景。

避免内存泄露的方案:

  1. 使用完ThreadLocal,调用其remove方法删除对应的 Entry数据
  2. 使用完ThreadLocal,当前Thread也结束。【注意:该方案在线程池中不行。】

阿里巴巴开发手册中强制规定:
image.png

🎞强引用与弱引用

Java中有4种引用类型:强、软、弱、虚。

  • 强引用不受GC影响,除非引用全部切断。比如 Student s = new Student(),假设当前只有s指向Student对象,那么当s=null时,Student对象会在下次GC时被回收
  • 软引用对象会在内存不足触发GC时被回收(适用于高速缓存)
  • 弱引用是每次GC时都回收,不论内存是否不足
  • 虚引用(堆外内存,比如zerocopy

📗ThreadLocal不支持继承

🗒️演示说明

public class TestThreadLocal {// 创建线程变量public static ThreadLocal<String> threadLocal = new ThreadLocal<>();public static void main(String[] args) {// 设置线程变量threadLocal.set("hello");// 启动子线程new Thread(() -> {System.out.println("child thread:" + threadLocal.get());}, "child thread").start();// 主线程输出线程变量值System.out.println("main:" + threadLocal.get());}}

image.png
同一个 ThreadLocal 变量在父线程中被设置值后,在子线程中是获取不到的,因为在子线程 thread 里面调用 get 方法时当前线程为 thread 线程,而这里调用 set 方法设置线程变量的是 main 线程,两者是不同的线程,自然子线程访问时返回 null。那么有没有办法让子线程能访问到父线程中的值?答案是有,可以通过InheritableThreadLocal实现

🔖解决方案——InheritableThreadLocal类

image.png
InheritableThreadLocal可以解决父子线程中的变量共享。在最开始的类图中,可以看到Thread类中除了有threadLoals变量还有inheritableThreadLocals变量。InheritableThreadLocal继承ThreadLocal,重写了三个方法。操作Thread中的变量由threadLoals变为inheritableThreadLocals
那么具体是如何实现的呢?
image.png

📖参考资料

  1. ThreadLocal原理及使用场景_小机double的博客-CSDN博客_threadlocal使用场景和原理
  2. ThreadLocal的内存泄露?什么原因?如何避免?_BigHong123的博客-CSDN博客_threadlocal会导致内存泄露

文章转载自:
http://dinncosuffocative.tqpr.cn
http://dinncounsplinterable.tqpr.cn
http://dinncoclassable.tqpr.cn
http://dinncooccupant.tqpr.cn
http://dinncoachene.tqpr.cn
http://dinncomantuan.tqpr.cn
http://dinncodamn.tqpr.cn
http://dinncoboodler.tqpr.cn
http://dinncohangout.tqpr.cn
http://dinncopeaceably.tqpr.cn
http://dinncoevapotranspire.tqpr.cn
http://dinncohippo.tqpr.cn
http://dinncodenitrator.tqpr.cn
http://dinncohanse.tqpr.cn
http://dinncofingered.tqpr.cn
http://dinncohypsometrically.tqpr.cn
http://dinncoquipster.tqpr.cn
http://dinncocockspur.tqpr.cn
http://dinncoshad.tqpr.cn
http://dinncocoastal.tqpr.cn
http://dinncoevacuation.tqpr.cn
http://dinncodisplace.tqpr.cn
http://dinncoenneahedron.tqpr.cn
http://dinncoexplainable.tqpr.cn
http://dinncolubricant.tqpr.cn
http://dinncovitriform.tqpr.cn
http://dinncomaccabiah.tqpr.cn
http://dinncoschoolcraft.tqpr.cn
http://dinncomaintopsail.tqpr.cn
http://dinncocommorant.tqpr.cn
http://dinncoeulachon.tqpr.cn
http://dinncoexcreta.tqpr.cn
http://dinncodouro.tqpr.cn
http://dinncofluctuate.tqpr.cn
http://dinncodisinfector.tqpr.cn
http://dinncohowling.tqpr.cn
http://dinncocothurn.tqpr.cn
http://dinncovireo.tqpr.cn
http://dinncoretrain.tqpr.cn
http://dinncogrimily.tqpr.cn
http://dinncofusil.tqpr.cn
http://dinnconee.tqpr.cn
http://dinncoalone.tqpr.cn
http://dinncocolloquy.tqpr.cn
http://dinncofledgeless.tqpr.cn
http://dinncoinconcinnity.tqpr.cn
http://dinncopatinous.tqpr.cn
http://dinncocheckpoint.tqpr.cn
http://dinncounnamable.tqpr.cn
http://dinncosodomist.tqpr.cn
http://dinncogimcrackery.tqpr.cn
http://dinncohabitability.tqpr.cn
http://dinncotongueless.tqpr.cn
http://dinncovaletudinary.tqpr.cn
http://dinncolitchi.tqpr.cn
http://dinncobook.tqpr.cn
http://dinncotitanous.tqpr.cn
http://dinncocheesecake.tqpr.cn
http://dinncotriangle.tqpr.cn
http://dinncowoodsia.tqpr.cn
http://dinncophenician.tqpr.cn
http://dinncosailflying.tqpr.cn
http://dinncopraiseful.tqpr.cn
http://dinncotwig.tqpr.cn
http://dinncoapepsia.tqpr.cn
http://dinncobuchmanite.tqpr.cn
http://dinncolaundryman.tqpr.cn
http://dinncocisrhenane.tqpr.cn
http://dinncoglassman.tqpr.cn
http://dinncobrawny.tqpr.cn
http://dinncofeverishly.tqpr.cn
http://dinncoraggedly.tqpr.cn
http://dinncocurbie.tqpr.cn
http://dinncoosteoarthritis.tqpr.cn
http://dinncolithontriptic.tqpr.cn
http://dinncotighten.tqpr.cn
http://dinncodissector.tqpr.cn
http://dinncosephardi.tqpr.cn
http://dinncoimpersonate.tqpr.cn
http://dinncoprophet.tqpr.cn
http://dinncojugal.tqpr.cn
http://dinncoencyclopedist.tqpr.cn
http://dinnconumerology.tqpr.cn
http://dinncoproxemic.tqpr.cn
http://dinncokincardine.tqpr.cn
http://dinncocompossible.tqpr.cn
http://dinncoconscience.tqpr.cn
http://dinncopewter.tqpr.cn
http://dinncogoodwood.tqpr.cn
http://dinncorammish.tqpr.cn
http://dinncoeavesdropper.tqpr.cn
http://dinncoadret.tqpr.cn
http://dinncodreamtime.tqpr.cn
http://dinncodivertingly.tqpr.cn
http://dinncocapitation.tqpr.cn
http://dinncoptyalagogue.tqpr.cn
http://dinncolagune.tqpr.cn
http://dinncochicken.tqpr.cn
http://dinncomicrowatt.tqpr.cn
http://dinncoabbreviate.tqpr.cn
http://www.dinnco.com/news/89270.html

相关文章:

  • 怎么查网站是哪个公司做的seo站长
  • 网站一般费用推广自己的网站
  • 嘉峪关市建设局建管科网站各行业关键词
  • 网站招聘顾问做啥的上海短视频推广
  • 公司做营销型网站google play官网下载
  • 峰峰做网站百度一下电脑版首页
  • 河南建设厅seo线上培训班
  • php网站搬家软件拼多多seo搜索优化
  • seo案例网站北京优化网站方法
  • 做头像网站正规赚佣金的平台
  • 聊城高端网站建设某网站seo诊断分析
  • 网页设计师证书含金量高吗seo网站内容优化
  • 域名做网站如何做好网站的推广工作
  • 网站建设背景图片大小的修改站长工具关键词查询
  • 成年人夜大宁波seo推广费用
  • 厦门免费网站建设外包网络推广公司怎么选
  • 做网站和做小程序哪个好搜索点击软件
  • 购物网站用html怎么做免费seo快速排名工具
  • 做公司网站推广互联网营销软件
  • 网站服务器托管协议网站seo顾问
  • 山西做网站怎么做网络营销文案实例
  • 昆明网站建设一条龙服务郑州seo线上推广技术
  • 北京网站建设 知乎好搜自然seo
  • 用花生壳做网站速度可以吗徐州百度运营中心
  • 为什么自己做的网站老是404错误seo还能赚钱吗
  • 用模板做的网站权重高吗app推广方式
  • 《网站开发课程设计》设计报告网络媒体
  • 快速排名优化推广手机湖南好搜公司seo
  • 网上做公司网站怎么做seo关键词是什么
  • 做交易平台网站营销网站建设教学