转自:
http://www.java265.com/JavaCourse/202205/3370.html
下文笔者讲述java中ThreadLocal的详解说明,如下所示:
ThreadLocal简介
- <strong>ThreadLocal的功能:
- 用于创建线程局部变量的类
- ----------------------------------------------------------------------------
- 我们都知道我们创建的变量,可以被任何一个线程访问和修改
- 但是当我们使用ThreadLocal创建的变量只能被当前线程访问,其他线程无法访问和修改
- -------------------------------------------------------------------------</strong>----
复制代码 ThreaLocal用法示例
- 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初始值--设置方法
ThreadLocal设置默认的get初始值
需要重写initialValue方法- 例:
- 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实例的弱引用。
复制代码 [code]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 |