转自:
http://www.java265.com/JavaCourse/202205/3370.html
下文笔者讲述java中ThreadLocal的详解说明,如下所示:
ThreadLocal简介
ThreadLocal的功能: 用于创建线程局部变量的类 ---------------------------------------------------------------------------- 我们都知道我们创建的变量,可以被任何一个线程访问和修改 但是当我们使用ThreadLocal创建的变量只能被当前线程访问,其他线程无法访问和修改 -----------------------------------------------------------------------------
ThreadLocal语法定义:
ThreadLocal定义: ThreadLocal<String> threadLocalInfo = new ThreadLocal<>(); set方法 threadLocalInfo.set(\"java265.com\"); get方法 threadLocalInfo.get(); 完整的示例 private void testThreadLocal() { Thread t = new Thread() { ThreadLocal<String> threadLocalInfo = new ThreadLocal<>(); @Override public void run() { super.run(); threadLocalInfo.set(\"java265.com--我最爱的网站\"); threadLocalInfo.get(); } }; t.start(); }
例: ThreadLocal<String> mThreadLocal = new ThreadLocal<String>() { @Override protected String initialValue() { return Thread.currentThread().getName(); } };
ThreadLocal的set方法原理说明
set方法源码: public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } getMap: ThreadLocalMap getMap(Thread t) { return t.threadLocals; } class Thread implements Runnable { ThreadLocal.ThreadLocalMap threadLocals = null; } 当一开始设置,即ThreadLocalMap对象未创建 则新建ThreadLocalMap对象,并设置初始值 void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); }
ThreadLocal导致内存泄露的原因说明
ThreadLocal实例被线程的ThreadLocalMap实例持有,也可以看成被线程持有。
当我们使用了线程池,由于之前的线程实例处理完之后出于复用的目的依然存活
即ThreadLocal设定的值被持有,才会导致内存泄露
ThreadLocal并不会产生内存泄露
因为ThreadLocalMap在选择key的时候
并不是直接选择ThreadLocal实例
而是ThreadLocal实例的弱引用
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 WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } } }
ThreadLocal使用场景
如:tractional 一个数据库连接,在一个线程中只此一份,所以可使用ThreadLocal实现线程间变量共享
来源:https://www.cnblogs.com/java265/p/16271786.html
本站部分图文来源于网络,如有侵权请联系删除。