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

长沙做网站设计找资源的关键词有哪些

长沙做网站设计,找资源的关键词有哪些,上海地区网站建设,公司官网制作报价ThreadLocal是一个存储线程本地变量的对象,在ThreadLocal中存储的对象在其他线程中是不可见的,本文介绍ThreadLocal的原理。 1、threadLocal使用 有如下代码: Slf4j public class TestThreadLocal {public static void main(String[] args…

ThreadLocal是一个存储线程本地变量的对象,在ThreadLocal中存储的对象在其他线程中是不可见的,本文介绍ThreadLocal的原理。

1、threadLocal使用

有如下代码:

@Slf4j
public class TestThreadLocal {public static void main(String[] args) {ThreadLocal<Integer> threadLocal = new ThreadLocal<>();threadLocal.set(999);log.info(threadLocal.get().toString());//使用线程池创建一个线程ExecutorService service = Executors.newSingleThreadExecutor();service.execute(()->{log.info(threadLocal.get().toString());//threadLocal.get()将为nullthreadLocal.set(888);log.info(threadLocal.get().toString());});log.info(threadLocal.get().toString());}
}
输出:
2023-03-09 09:03:40.572 [main] INFO -- 999
2023-03-09 09:03:40.598 [main] INFO -- 999
Exception in thread "pool-1-thread-1" java.lang.NullPointerExceptionat com.iwat.arithmetic.thread.TestThreadLocal.lambda$main$0(TestThreadLocal.java:24)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at java.lang.Thread.run(Thread.java:748)

从结果中可以看到,在新线程中无法获取到999,祝线程中set的数,只有祝线程能get到,这就保证了变量的线程唯一。

2、原理

原理就要看源码
首先看threadLocal.set(999);的源码

	//ThreadLocal类中public void set(T value) {//1.获取当前线程Thread t = Thread.currentThread();//2. 获取线程中的ThreadLocalMap对象ThreadLocalMap map = getMap(t);if (map != null)//线程中的ThreadLocalMap对象不为空,直接set值,this就是当前ThreadLocal对象没,值就是值map.set(this, value);else//线程中的ThreadLocalMap对象为空,创建并set值createMap(t, value);}

很简单,获取当前线程,然后获取当前线程的ThreadLocalMap对象,这里的ThreadLocalMap可以就当做一个Map处理,但是这个Map不一样的地方在于key只能是ThreadLocal对象。现在我们就可以分析一下了。

在这里插入图片描述

每一线程都有一个ThreadLocalMap对象,对于每一个ThreadLocal对象来说它可以在每一个线程中ThreadLocalMap中存一个以它为key的值。例如:

  • 在线程1中,ThreadLocal对象1执行set方法,实际上就是在线程1中的ThreadLocalMap中添加一个k-v(1号红色箭头),k就是ThreadLocal对象1。
  • 在线程1中,ThreadLocal对象2执行get方法,就是在线程1的ThreadLocalMap中获取以ThreadLocal对象2为key的值(2号红色箭头)

每个ThreadLocal在某个线程中只能有一个对应value,因为Map中key不能重复,这就实现了线程唯一变量的功能。

下面看一下ThreadLocal中的get方法验证一下分析:

	//ThreadLocal类中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();}

同时这也解释了,为什么上面代码中出现Exception in thread "pool-1-thread-1" java.lang.NullPointerException,原因就是在新创建的线程中的ThreadLocalMap中没有以当前ThreadLocal对象为key的值。

3、java引用类型

3.1 GC回收对象

java垃圾回收器多采用可达性分析算法来确定一个java对象需不需要回收,过程是这样的:

  • 首先确定一些一定不能回收的对象,叫做GCRoot对象
  • 查找GCRoot对象引用的对象
  • 然后沿着引用链一直找(注意:引用有多种类型)

最终根据对象被引用的类型、有没有被引用,来决定是不是回收这个对象。

3.2 引用类型

那么引用类型有哪些呢?总体而言分为四种:

  1. 强引用
    沿着GC Root引用链可以找到的对象就是强引用对象
  2. 软引用 (SoftReference)
    垃圾回收后仍内存不足,就会回收掉
  3. 弱号1用 (WeakReference)
    垃圾回收就将其回收掉
  4. 虚引用 (PhantomReference)
    必须配合引用队列使用,主要配合 ByteButfer 使用,被引用对象回收时,会将虛引用入队,由
    Reference Handler 线程调用虚引用相关方法释放直接内存

在这里插入图片描述

4、内存泄漏问题

在看了java中几种引用类型之后在看内存泄漏问题,什么是内存泄漏?就是指一部分对象一直占用内存,也清不掉,就好像这块内存空间没了,漏掉了。

其实在ThreadLocalMap的内部使用的是Entry类存储k-v

static class ThreadLocalMap {static class Entry extends WeakReference<ThreadLocal<?>> {/** The value associated with this ThreadLocal. */Object value;Entry(ThreadLocal<?> k, Object v) {super(k);value = v;}}/*** The initial capacity -- MUST be a power of two.*/private static final int INITIAL_CAPACITY = 16;//省略若干代码
}

可以看到Entry在实现时继承了弱引用,为什么这样呢?看注释是这样说的

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.Note that null keys (i.e. entry.get()* == null)
如果 key threadlocal 为 null 了,这个 entry 就可以清除了。
ThreadLocal是一个弱引用,当为null时,会被当成垃圾回收 。

在ThreadLocal的使用时,线程的ThreadLocalMap中都存储了以ThreadLocal为key的值,如果ThreadLocal被清理了,那么
ThreadLocalMap中对应的数据会被清理吗?
并不会,原因是ThreadLocal被清理变成null之后,ThreadLocalMap被Thread所引用(强引用)并不会回收,只是key变成了null。

如何解决呢内存泄漏呢?最简单的办法就是用完之后remove,ThreadLocal不用了,就去ThreadLocalMap中清理到对用的k-v。

http://www.hkea.cn/news/843802/

相关文章:

  • 深圳福田网站建设公司如何做谷歌seo推广
  • 西安有做网站的吗北京网站设计公司
  • 哪家专门做特卖网站平台连接
  • 衢州网站推广最近发生的重大新闻
  • 网页设计的网站配色方案seo基础培训机构
  • 维护网站是什么工作淄博网站制作
  • 做电影下载网站成本淘宝关键词排名
  • 企业h5网站建设百度推广电话是多少
  • 中国保密在线网站培训系统软文怎么做
  • 山西住房城乡建设部网站整合网络营销是什么
  • 做美图网站有哪些东西吗个人博客seo
  • 南昌专业做网站公司竞价托管怎么做
  • 网站产品展示怎么做微信小程序建站
  • dw做网站的流程客户引流的最快方法是什么
  • 做网站app优惠活动的交换链接营销成功案例
  • 企业公示信息查询系统山西上海百度推广优化公司
  • 上海网站排名优化价格武汉百度快照优化排名
  • 做网站小程序如何做广告宣传与推广
  • 网站建设背景朝阳百度新闻网页
  • 专门做拼团的网站西安网站开发
  • 怎么看网站开发语言太原seo推广
  • 什么网站做宣传好新乡网站seo
  • 济南网站制作服务价格信息流优化师前景
  • 新手制作网站工具bt磁力猪
  • 怎么做网站系统深圳头条新闻
  • 北京网站设计公司新鸿儒seo公司的选上海百首网络
  • 百姓网二手拖拉机百度seo优化排名客服电话
  • 北京南站是丰台站吗seo优化什么意思
  • 外贸营销型建站关键词全网搜索工具
  • 有什么网站可以做扣扣头像腾讯企点app下载安装