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

专业网站建设公司哪里济南兴田德润什么活动上海景观设计公司10强

专业网站建设公司哪里济南兴田德润什么活动,上海景观设计公司10强,建立网站的步骤,珠海移动网站建设公司排名文章目录 前言一、ThreadLocal 是什么?二、有哪些使用场景?三、实现原理四、在线程池中使用 ThreadLocal 为什么可能导致内存泄露呢?五、线程池中,如何正确使用 ThreadLocal?六、ThreadLocal 核心方法 前言 一、Threa…

文章目录

  • 前言
  • 一、ThreadLocal 是什么?
  • 二、有哪些使用场景?
  • 三、实现原理
  • 四、在线程池中使用 ThreadLocal 为什么可能导致内存泄露呢?
  • 五、线程池中,如何正确使用 ThreadLocal?
  • 六、ThreadLocal 核心方法

前言

一、ThreadLocal 是什么?

ThreadLocal 是线程本地存储,在每个线程中都创建了一个 ThreadLocalMap 对象,每个线程可以访问自己内部 ThreadLocalMap 对象内的 value。

二、有哪些使用场景?

经典的使用场景是为每个线程分配一个 JDBC 连接 Connection。这样就可以保证每个线程的都在各自的 Connection 上进行数据库的操作,不会出现 A 线程关了 B线程正在使用的 Connection; 还有 Session管理等问题。

ThreadLocal 使用例子:

public class TestThreadLocal {//线程本地存储变量private static final ThreadLocal<Integer> THREAD_LOCAL_NUM = new ThreadLocal<Integer>() {@Overrideprotected Integer initialValue() {return 0;}};public static void main(String[] args) {for (int i = 0; i < 3; i++) {//启动三个线程Thread t = new Thread() {@Overridepublic void run() {add10ByThreadLocal();}};t.start();}}/*** 线程本地存储变量加 5*/private static void add10ByThreadLocal() {for (int i = 0; i < 5; i++) {Integer n = THREAD_LOCAL_NUM.get();n += 1;THREAD_LOCAL_NUM.set(n);System.out.println(Thread.currentThread().getName() + " : ThreadLocal num=" + n);}}}

打印结果:启动了 3 个线程,每个线程最后都打印到 “ThreadLocal num=5”,而不是 num 一直在累加直到值等于 15

Thread-0 : ThreadLocal num=1
Thread-1 : ThreadLocal num=1
Thread-0 : ThreadLocal num=2
Thread-0 : ThreadLocal num=3
Thread-1 : ThreadLocal num=2
Thread-2 : ThreadLocal num=1
Thread-0 : ThreadLocal num=4
Thread-2 : ThreadLocal num=2
Thread-1 : ThreadLocal num=3
Thread-1 : ThreadLocal num=4
Thread-2 : ThreadLocal num=3
Thread-0 : ThreadLocal num=5
Thread-2 : ThreadLocal num=4
Thread-2 : ThreadLocal num=5
Thread-1 : ThreadLocal num=5

三、实现原理

按照我们第一直觉,感觉 ThreadLocal 内部肯定是有个 Map 结构,key 存了 Thread,value 存了 本地变量 V 的值。每次通过 ThreadLocal 对象的 get() 和 set(T value) 方法获取当前线程里存的本地变量、设置当前线程里的本地变量。

在这里插入图片描述

而 JDK 的实现里面这个 Map 是属于 Thread,而非属于 ThreadLocal。ThreadLocal 仅是一个代理工具类,内部并不持有任何与线程相关的数据,所有和线程相关的数据都存储在 Thread 里面。ThreadLocalMap 属于 Thread 也更加合理。

还有一个更加深层次的原因,这样设计不容易产生内存泄露。
ThreadLocal 持有的 Map 会持有 Thread 对象的引用,只要 ThreadLocal 对象存在,那么 Map 中的 Thread 对象就永远不会被回收。ThreadLocal 的生命周期往往比线程要长,所以这种设计方案很容易导致内存泄露。

JDK 的实现中 Thread 持有 ThreadLocalMap,而且 ThreadLocalMap 里对 ThreadLocal 的引用还是弱引用(WeakReference),所以只要 Thread 对象可以被回收,那么 ThreadLocalMap 就能被回收。JDK 的这种实现方案复杂但更安全。

在这里插入图片描述

四、在线程池中使用 ThreadLocal 为什么可能导致内存泄露呢?

在线程池中线程的存活时间太长,往往都是和程序同生共死的,这样 Thread 持有的 ThreadLocalMap 一直都不会被回收,再加上 ThreadLocalMap 中的 Entry 对 ThreadLocal 是弱引用(WeakReference),所以只要 ThreadLocal 结束了自己的生命周期是可以被回收掉的。
Entry 中的 Value 是被 Entry 强引用的,即便 value 的生命周期结束了,value 也是无法被回收的,导致内存泄露。

五、线程池中,如何正确使用 ThreadLocal?

在 finally 代码块中手动清理 ThreadLocal 中的 value,调用 ThreadLocal 的 remove()方法。

六、ThreadLocal 核心方法

  • 设置 Thread 对应的 Value 值,首次会创建一个 ThreadLocalMap ,添加 ThreadLocal - Value 到 ThreadLocalMap 中,并且绑定 ThreadLocalMap 到当前线程。
public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);
}
  • 创建 ThreadLocalMap,绑定到当前线程。
void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue);
}
  • 通过 ThreadLocalMap 获取当前线程的存储的 Value 值
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 的初始化值,未 set(T value) 初次获取 Thread 对应的 Value 值时会调用,即被 setInitialValue 方法调用。需要重写该方法。
protected T initialValue() {return null;
}
  • 移除当前线程存储的 Value 值。当 ThreadLocal 不在使用,最好在 finally 语句块中,调用 remove() 方法,释放去 Value 的引用,避免内存泄露。
public void remove() {ThreadLocalMap m = getMap(Thread.currentThread());if (m != null)m.remove(this);
}
http://www.sczhlp.com/news/82085/

相关文章:

  • 网站和h5开平网络推广
  • 番禺高端网站建设视频拍摄团队
  • 做捕鱼网站电话号码wordpress菜单怎么设置中文
  • 专业网站建设模块维护网站建设邀标函
  • 成品软件网站推荐wordpress主题 食品
  • 阿里云做网站用哪个镜像企业年底做网站的好处
  • 收录网站工具手机优化大师下载
  • 广州 网站设计公司排名做机械的老板都看什么网站
  • 初识Dataset
  • Day15可变参数
  • visual c 网站开发sem和seo是什么
  • wordpress建站公司建筑防护网安全网
  • 福州网站建设找时时在网络wordpress直播流插件
  • 暖通设计网站推荐洛阳建设信息网站
  • 建设网站几种方法cms二次开发网站建设
  • 海口专业网站制作策划公司推广咨询
  • 学网站建设有前途吗化工网站制作
  • 常宁市城乡和住房建设网站上海建筑业网证书查询
  • 成都网站建设四川冠辰科技大专毕业设计怎么做
  • 适合学生做的网站wordpress改字体颜色
  • 南京做网站企业网站设计 培训
  • 网站建设品牌排行榜外包公司被辞退有补偿吗
  • 网站建设中应注意哪些问题做网站容易学吗
  • 烟台做网站的企业互联网公司排名类比
  • 丹灶网站建设公司大数据营销笔记本
  • Python模块之 subprocess 具有可访问I/O流的子流程 子进程管理
  • 因爱而……(和谐版)
  • 初探CTF
  • 网站建设客户电影网站做流量吗
  • 网站系统管理功能潜江资讯网找工作