当前位置:首页 > 技术 >

threadlocal的底层原理(threadlocal实际中的作用)

来源:原点资讯(www.yd166.com)时间:2023-04-15 23:59:19作者:YD166手机阅读>>

1、ThreadLocal的底层原理图

threadlocal的底层原理,threadlocal实际中的作用(1)

说明:Thread中有threadLocals成员变量,threadLocal会在threadlocal首次set时进行赋值【这会在非main线程中复现,主线程启动即会进行赋值】,ThreadLocalMap是ThreadLocal的静态内部类,在set时,会将我们新建threadLocal引用地址作为key,以此封装成一个Entry<threadLocal<?>,Object>对象,可以存在多个不同的threadlocal,如果set的引用地址相同,就会进行覆盖,此处key的类型ThreadLocal继承弱引用也是会造成内存泄露的主要原因,在下面源码中会对此段相关点分别说明。

2.源码解析

package com.adun.test_threadlocal; /** * @author ADun * @date 2022/4/27 11:14 */ public class ThreadLocalTest { public static final ThreadLocal<Integer> threadLocal = new ThreadLocal(); public static final ThreadLocal<Integer> threadLocal2 = new ThreadLocal(); public static void main(String[] args) { threadLocal.set(1234); Integer num1 = threadLocal.get(); System.out.println(num1); Integer num2 = threadLocal.get(); System.out.println(num2); threadLocal2.set(111); System.out.println(threadLocal2.get()); //最后必须remove,避免内存泄露 threadLocal.remove(); threadLocal2.remove(); } }

ThreadLocal中的set方法以及涉及到的相关方法

public void set(T value) { Thread t = Thread.currentThread(); //获取当前线程的threadLocals ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else //如果获取不到当前线程的threadlocals成员变量,则新建并将value放入 createMap(t, value); }

/** * 获取当前线程的threadlocals * Get the map associated with a ThreadLocal. Overridden in * InheritableThreadLocal. * * @param t the current thread * @return the map */ ThreadLocalMap getMap(Thread t) { return t.threadLocals; } /** * 创建ThreadLocalMap,并对当前线程的threadlocals进行赋值 * Create the map associated with a ThreadLocal. Overridden in * InheritableThreadLocal. * * @param t the current thread * @param firstValue value for the initial entry of the map */ void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); }

ThreadLocal静态内部类ThreadLocalMap

/** * 初始化ThreadLocalMap的构造器 * Construct a new map initially containing (firstKey, firstValue). * ThreadLocalMaps are constructed lazily, so we only create * one when we have at least one entry to put in it. */ ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) { table = new Entry[INITIAL_CAPACITY]; int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1); table[i] = new Entry(firstKey, firstValue); size = 1; setThreshold(INITIAL_CAPACITY); } /** * 玩当前线程的threadlocals对应的threadLocalMap中赋值 * 用户new的threadlocal的引用地址作为key,value作为value进行赋值构建Entry对象,如果已存在,则进行覆盖 * Set the value associated with key. * * @param key the thread local object * @param value the value to be set */ private void set(ThreadLocal<?> key, Object value) { // We don't use a fast path as with get() because it is at // least as common to use set() to create new entries as // it is to replace existing ones, in which case, a fast // path would fail more often than not. //Entry<ThreadLocal<?>,Object>数组,存放多个threadlocal的数据 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)]) { ThreadLocal<?> k = e.get(); if (k == key) { e.value = value; return; } if (k == null) { replaceStaleEntry(key, value, i); return; } } tab[i] = new Entry(key, value); int sz = size; if (!cleanSomeSlots(i, sz) && sz >= threshold) rehash(); }

ThreadLocalMap内部类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. */ static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; //Entry继承弱引用,弱引用的特点是在jvm进行gc扫描中直接进行回收 //这种操作既有可能k的引用被回收,而v的值失去所有到达的引用,造成内存泄露,所以在最后必须remove Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } }

栏目热文

threadlocal实例(threadlocal使用范例)

threadlocal实例(threadlocal使用范例)

作者:@adamhandzybuluo.com/adamhand/note/1370920ThreadLocal是什么首...

2023-04-15 23:56:45查看全文 >>

threadlocal 使用场景(threadlocal详细介绍)

threadlocal 使用场景(threadlocal详细介绍)

两大使用场景-ThreadLocal的用途典型场景1: 每个线程需要一个独享的对象(通常是工具类,典型需要使用的类有Si...

2023-04-15 23:45:51查看全文 >>

threadlocal底层原理(ThreadLocal原理)

threadlocal底层原理(ThreadLocal原理)

引言这是JWT认证条件下的getCurrentLoginUser代码实现,请分析性能:在生产环境中,currentLog...

2023-04-15 23:51:07查看全文 >>

threadlocal用法示例(threadlocal使用场景)

threadlocal用法示例(threadlocal使用场景)

1.ThreadLocal的使用场景1.1 场景1每个线程需要一个独享对象(通常是工具类,典型需要使用的类有Simple...

2023-04-15 23:54:10查看全文 >>

threadlocal使用场景(threadlocal不能使用的场景)

threadlocal使用场景(threadlocal不能使用的场景)

推荐学习 前言相信很多同学都听过threadLocal,即使没用过也听过。但是要仔细一问ThreadLocal是个啥,...

2023-04-15 23:59:17查看全文 >>

threadlocal 存在意义(threadlocal存在哪里)

threadlocal 存在意义(threadlocal存在哪里)

功能迭代,在代码层面小编有1w种实现方法(吹牛的),一起来看看这次小编如何使用ThreadLocal优雅地完成本次迭代吧...

2023-04-15 23:15:22查看全文 >>

javathreadlocal原理(java thread 方法详解)

javathreadlocal原理(java thread 方法详解)

图解:该图基于Android中的ThreadLocal在Looper中的应用,其能够实现一个线程只有一个Looper的私...

2023-04-15 23:23:59查看全文 >>

thread local使用场景和原理

thread local使用场景和原理

是什么ThreadLocal从名字上看好像是一个Thread,其实并不是,它是Therad的局部变量的维护类。作用是让变...

2023-04-15 23:35:49查看全文 >>

柿子树风水大忌(旺宅最好的树)

柿子树风水大忌(旺宅最好的树)

“前不栽桑,后不栽柳,刀锯不上槐树身,院中不栽鬼拍手”,都是农村的一些带有迷信色彩的讲究。随着科学知识的普及,这些讲究忌...

2023-04-15 23:28:56查看全文 >>

柿子树种到院子里禁忌(柿子树栽在庭院什么位置好)

柿子树种到院子里禁忌(柿子树栽在庭院什么位置好)

提要:柿子树在院子当中种植好吗?柿子树是我国一个历史悠久的果木之一,因为柿子树所结的果实红彤彤颜色极佳,秋天成熟季节树上...

2023-04-15 23:21:05查看全文 >>

文档排行