IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 面试扫盲系列之:ThreadLocal 原理 -> 正文阅读

[Java知识库]面试扫盲系列之:ThreadLocal 原理

咋个使用?

ThreadLocal<String> localName = new ThreadLocal();
localName.set("xx");
String name = localName.get();

原理

public class ThreadLocal<T> {
	public void set(T value) {
		Thread t = Thread.currentThread();
		ThreadLocalMap map = getMap(t);
		if (map != null)
			map.set(this, value);
		else
			createMap(t, value);
	}


    void createMap(Thread t, T firstValue) {
		t.threadLocals = new ThreadLocalMap(this, firstValue);
	}
}

首先看set方法,实际上value是存在ThreadLocalMap的,Thread类自带ThreadLocalMap成员

【也就是一个线程有一个map专门用来存threadlocal对象作为key的数据,解决hash冲突是用开放地址法】,

for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) //开放地址

可以看到ThreadLocal是一个弱引用,那么当GC线程扫描的过程中一旦发现某个对象只具有弱引用而不存在强引用时不管当前内存空间足够与否GC都会回收它的内存。【为了防止内存溢出,在处理一些占用内存大而且生命周期较长的对象时候,可以尽量使用软引用和弱引用。

【理解弱引用例子:Java弱引用WeakReference理解,这一篇就够了!_程冯冯的博客-CSDN博客_继承弱引用

static class ThreadLocalMap {
    static class Entry extends WeakReference<ThreadLocal<?>> {
			Object value;
			Entry(ThreadLocal<?> k, Object v) {
				super(k);
				value = v;
			}
		}
}

内存泄漏?

        // 有强引用指向ThreadLocal对象
        ThreadLocal<String> threadLocal = new ThreadLocal<>();
        threadLocal.set("abc");

        // 没有强引用指向ThreadLocal对象
        new ThreadLocal<>().set("def");

没有强引用存在时,弱引用指向的对象会被垃圾回收器回收。不过,这里key虽然被回收了,但是value依然会出现内存泄漏问题。只有当线程生命周期结束,或者触发清理算法时,value才能被gc回收。

如果此时,我们ThreadLocal对象也是一个静态常量,那么在下一次线程被使用的时候,很可能获取到的是之前保存的数据,导致脏数据。

如何避免内存泄漏?

及时remove

		private void remove(ThreadLocal<?> key) {
			Entry[] tab = table;
			int len = tab.length;
			int i = key.threadLocalHashCode & (len - 1);
			for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) {
				if (e.get() == key) {
					e.clear();
					expungeStaleEntry(i);
					return;
				}
			}
		}

神奇的 0x61c88647

使得hash 分布非常均匀。【ThreadLocal 面试看这一篇就够了_晓呆同学的专栏-CSDN博客

int h = key.threadLocalHashCode & (len - 1);

要是新来一个数要算其hash值,key.threadLocalHashCode是在原来基础上加了0x61c88647的

InheritableThreadLocal?

使用ThreadLocal时,子线程获取不到父线程通过set方法保存的数据,要想使子线程也可以获取到,可以使用InheritableThreadLocal类。

public class InheritableThreadLocal<T> extends ThreadLocal<T> {

    protected T childValue(T parentValue) {
        return parentValue;
    }

    ThreadLocalMap getMap(Thread t) {
       return t.inheritableThreadLocals;
    }

    void createMap(Thread t, T firstValue) {
        t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
    }
}

原理超级简单,当调用set时,实际是往Thread类的ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;? 这里面写的,为啥子线程可以拿到?

public class Thread implements Runnable {
  private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) {

    if (parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
}}

子线程中数据是从父线程拷贝来的,所以,在子线程中重新set的内容,对于父线程是不可见的。

可以参考的其他资料

Java面试必问,ThreadLocal终极篇 - 简书

面试题:由ThreadLocal引发的惨案_zuihongyan518的博客-CSDN博客_threadlocal 面试

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-01-29 22:56:59  更:2022-01-29 22:59:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:27:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码