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

看会员视频的网站开发毕设网站建设论文

看会员视频的网站开发,毕设网站建设论文,高级工程师,做企业平台的网站使用ThreadLocal可以为每个线程维护一个线程变量#xff0c;使用场景为线程间隔离#xff0c;线程内方法共享#xff1b; 原理#xff1a; Thread类中有一个实例属性ThreadLocalMap#xff0c;ThreadLocalMap中存放的是Entry数组#xff0c;Entry数组是ThreadLocal和Ob…使用ThreadLocal可以为每个线程维护一个线程变量使用场景为线程间隔离线程内方法共享 原理 Thread类中有一个实例属性ThreadLocalMapThreadLocalMap中存放的是Entry数组Entry数组是ThreadLocal和Object的键值对源码如下-- Thread类 /** ThreadLocal values pertaining to this thread. This map is maintained* by the ThreadLocal class. */ ThreadLocal.ThreadLocalMap threadLocals; ThreadLocal-ThreadLocalMap-Entry类 static class ThreadLocalMap {/*** The entries in this hash map extend WeakReference, using* its main ref field as the key (which is always a* ThreadLocal object). Note that null keys (i.e. entry.get()* null) mean that the key is no longer referenced, so the* entry can be expunged from table. Such entries are referred to* as stale entries in the code that follows.*/static class Entry extends WeakReferenceThreadLocal? {/** The value associated with this ThreadLocal. */Object value;Entry(ThreadLocal? k, Object v) {super(k);value v;}}ThreadLocal有一个内部静态类ThreadLocalMap, ThreadLocalMap是一个Entry数组通过map方法来访问数据而Entry对keyThreadLocal实例对象的引用使用了虚引用这里导致key可能会在JVM判断oom之前将key回收掉导致内存泄漏-此时key对应的ThreadLocal对象被回收变成null而value存在Thread reference-thread-threadlocalMap-entry-value的强引用链导致无法回收虽然在ThreadLocal的get和set以及remove方法中实现了检查是否存在key为null并清理value的机制但是无法避免内存短时间内泄露的问题 看一下ThreadLocal的set和get()方法-- public void set(T value) {set(Thread.currentThread(), value);}private void set(Thread t, T value) {ThreadLocalMap map getMap(t);if (map ! null) {map.set(this, value);} else {createMap(t, value);}}ThreadLocalMap getMap(Thread t) {return t.threadLocals;} public T get() {return get(Thread.currentThread());}private T get(Thread t) {//获取当前线程的ThreadLocalMapThreadLocalMap map getMap(t);if (map ! null) {ThreadLocalMap.Entry e map.getEntry(this);if (e ! null) {T result (T) e.value;return result;}}return setInitialValue(t);}private Entry getEntry(ThreadLocal? key) {//这里进行map操作和hashmap的原理基本是一样的hashcode按位与数组长度减一数组长度默认为162的n次方减一值做按位与相当于取模保证了散列均衡int i key.threadLocalHashCode (table.length - 1);Entry e table[i];if (e ! null e.refersTo(key))return e;elsereturn getEntryAfterMiss(key, i, e);} 所以ThreadLocal维护为每一个线程维护线程变量副本的原理在于每个线程对象会创建自己的THreadLocalMap--这里并非主动创建而是调用THreadLocal的set或者get方法的时候才创建而ThreadLocalMap则是一个以ThreadLocal实例对象的弱应用为keyObject对象为value的键值对数组以便每个线程对象存放多个线程变量而对这个线程变量的访问是通过ThreadLocal对象来操作的所以说实现线程变量的根本不在于ThreadLocal而是ThreadLocalMap而ThreadLocal对象只是访问该线程的ThreadLocalMap的一个入口由于get(Thread t)和setThread tT value都是私有方法通过其他对象无法访问所以只能通过ThreadLocal对象提供的重载方法get()和set(Object value)来访问保证了线程变量的安全性---其他线程无法修改另外一个线程的ThreadLocalMap所以核心是getMapThread t,而这里的线程对象t只能是Thread.currentThread 另外需要注意的是对ThreadLocal 保存的线程变量一定要在使用完之后及时remove掉一个原因是防止内存泄漏更重要的原因是在线程池场景下一个请求可能会读取到上一个请求保存的变量内容从而造成业务逻辑上的BUG而且这种BUG还是不易排查的 另外关于内存泄露的问题JDK提供了一些保障,分为启发式清理和探测式清理-- 探测式清理-- 原理 删除当前元素继续往后遍历 当keynull的时候删除value当key!null的时候将因哈希碰撞后移的元素重新放置----ThreadLocalMap中使用了后移解决哈希碰撞 源码 private int expungeStaleEntry(int staleSlot) {Entry[] tab table;int len tab.length;// 删除当前元素--value置为nullvalue引用的对象变成了无引用对象会被回收同样的将数组上该位置的Entry对象置空原来的Entry对象也会被回收掉tab[staleSlot].value null;tab[staleSlot] null;size--;// Rehash until we encounter nullEntry e;int i;//继续遍历for (i nextIndex(staleSlot, len);(e tab[i]) ! null;i nextIndex(i, len)) {ThreadLocal? k e.get();//key为空的时候继续删除if (k null) {e.value null;tab[i] null;size--;} else {//key 不为空的时候rehash重新计算该key的下标---这里需要注意--rehash的结果可能和原来的值是一样的因为不能完全保证是否产生过哈希碰撞int h k.threadLocalHashCode (len - 1);if (h ! i) {tab[i] null;// Unlike Knuth 6.4 Algorithm R, we must scan until// null because multiple entries could have been stale.while (tab[h] ! null)h nextIndex(h, len);tab[h] e;}}}return i;} 启发式清理-- 往后遍历如果找到key为null的过期元素 则调用探测式清理--启发式清理可以理解为为探测式清理找到一个清理入口由探测式清理完成具体的清理工作 private boolean cleanSomeSlots(int i, int n) {boolean removed false;Entry[] tab table;int len tab.length;do {i nextIndex(i, len);Entry e tab[i];if (e ! null e.refersTo(null)) {n len;removed true;i expungeStaleEntry(i);}} while ( (n 1) ! 0);return removed;}另外看一下清理工作在哪里被调用-- set(Thread t,T value)-cleabSomeSlots();set(Thread t,T value)-replaceStaleEntry()-cleanSomeSlots();get(t)-getEntry()-getEntryAfterMiss()-expungeStaleEntry();remove()-expungeStaleEntry();rehash()-expungeStaleEntries-expungeStaleEntry() 上边的调用关系可以看出来基本上我们对ThreadLocal的getsetremove操作都会触发清理工作尽量减小了内存泄漏带来的影响---在未做任何操作之前不会主动触发清理所以在使用ThreadLocal的时候及时调用remove很重要
http://www.dnsts.com.cn/news/120195.html

相关文章:

  • 网站加关键词代码线上营销活动方案
  • 授权网站系统网站开发路线
  • 推荐一个免费的网站网站建设中常用的音频格式和视频格式
  • 南京建设工程质量监督站网站用php做网站难吗
  • 怎么查有做网站的公司有哪些微网站与移动开发是做什么的
  • 镜像网站做优化网站建设备案多长时间
  • 禄丰网站建设做网站一定要用云解析吗
  • 萍乡网站推广专业网架公司
  • 哈尔滨双城区建设局网站想开个网站做外贸怎么做
  • wordpress建站系统视频教程网页界面设计论文
  • 网站运营推广怎做网站设置访问权限
  • 普洱专业企业网站建设在线制作图网站
  • 德清县建设银行官方网站空间做网站
  • ppt 如何做网站交互式什么是网络营销的综合工具
  • 模板式网站价格网站建设的背景意义
  • 网站生成系统源码校园招聘网站开发研究背景
  • 商城网站续费要多少钱网站开发提案
  • 网站后台用户名营销策略英文
  • 包头手机网站制作创建一个网站的创业计划书
  • 双城网站建设公司低价网站建设费用多少
  • 物流网站建设与管理规划书小程序开发小程序制作
  • 建设一个农家乐网站怎么样查中企动力做的网站
  • 电商网站建设设计报告总结wordpress需注册访问
  • 网站建设灬金手指下拉十五电脑网站建设策划书
  • 怎么做网站自动采集数据电子商务网站建设的流程图
  • 学网站建设怎么样网站建设论文答辩自述
  • vs网站界面是什么做的梧州论坛一红豆社区
  • 哈尔滨建站多少钱可以做仿牌网站
  • 网站模板开发网站优秀设计方案
  • 刘涛做的儿童购物网站在线代理入口