马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
ThreadLocal 的实现涉及到 Java 内部的许多细节,紧张依赖于每个线程维护的一个 ThreadLocalMap 对象。以下是 ThreadLocal 实现的关键部分:
1. ThreadLocal 类
ThreadLocal 类本身提供了一些公共方法,如 get()、set() 和 remove(),这些方法现实上是对 ThreadLocalMap 举行操作。
- public class ThreadLocal<T> {
- // 初始化 ThreadLocal 值
- protected T initialValue() {
- return null;
- }
- // 获取当前线程的 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();
- }
- // 设置当前线程的 ThreadLocal 值
- public void set(T value) {
- Thread t = Thread.currentThread();
- ThreadLocalMap map = getMap(t);
- if (map != null)
- map.set(this, value);
- else
- createMap(t, value);
- }
- // 移除当前线程的 ThreadLocal 值
- public void remove() {
- ThreadLocalMap m = getMap(Thread.currentThread());
- if (m != null)
- m.remove(this);
- }
- // 初始化值并放入 ThreadLocalMap
- private T setInitialValue() {
- T value = initialValue();
- Thread t = Thread.currentThread();
- ThreadLocalMap map = getMap(t);
- if (map != null)
- map.set(this, value);
- else
- createMap(t, value);
- return value;
- }
- // 获取当前线程的 ThreadLocalMap
- ThreadLocalMap getMap(Thread t) {
- return t.threadLocals;
- }
- // 创建 ThreadLocalMap
- void createMap(Thread t, T firstValue) {
- t.threadLocals = new ThreadLocalMap(this, firstValue);
- }
- // 内部类 ThreadLocalMap
- static class ThreadLocalMap {
- // ...
- // 定义 Entry
- static class Entry extends WeakReference<ThreadLocal<?>> {
- Object value;
- Entry(ThreadLocal<?> k, Object v) {
- super(k);
- value = v;
- }
- }
-
- // 存储 Entry 的数组
- private Entry[] table;
-
- // 初始化
- 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);
- }
-
- // 获取 Entry
- private Entry getEntry(ThreadLocal<?> key) {
- int i = key.threadLocalHashCode & (table.length - 1);
- Entry e = table[i];
- if (e != null && e.get() == key)
- return e;
- else
- return getEntryAfterMiss(key, i, e);
- }
-
- // 设置值
- private void set(ThreadLocal<?> key, Object value) {
- 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();
- }
-
- // 移除 Entry
- 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;
- }
- }
- }
-
- // 其他方法...
- }
- }
复制代码 2. Thread 类中的 ThreadLocalMap
每个线程都有一个 ThreadLocalMap,这个 ThreadLocalMap 是 Thread 类中的一个成员变量,用于存储该线程的 ThreadLocal 变量。
- public class Thread implements Runnable {
- // 每个线程都持有一个 ThreadLocalMap
- ThreadLocal.ThreadLocalMap threadLocals = null;
-
- // 其他线程相关方法和属性...
- }
复制代码 3. ThreadLocalMap 实现
ThreadLocalMap 是 ThreadLocal 类的一个静态内部类,用于存储线程局部变量。它利用 ThreadLocal 的 hashCode 作为键,将值存储在一个 Entry 数组中。Entry 继承自 WeakReference,利用弱引用来防止内存泄漏。
- 弱引用:ThreadLocalMap 中的 Entry 利用弱引用来引用 ThreadLocal 实例,制止内存泄漏。当一个 ThreadLocal 实例不再被其他强引用引用时,GC 可以回收它,而不必要显式地移除 Entry。
4. 哈希算法和辩论解决
ThreadLocalMap 利用哈希算法将 ThreadLocal 实例的 hashCode 映射到 Entry 数组的索引位置。假如发生哈希辩论,则利用线性探测法解决辩论。
5. 内存管理
ThreadLocalMap 利用 WeakReference 以及定期清算逾期条目来管理内存。通过这些机制,可以防止内存泄漏,即使线程长期存在,已经不再利用的 ThreadLocal 变量也可以被 GC 回收。
总结
ThreadLocal 通过每个线程维护一个独立的 ThreadLocalMap,并利用弱引用来管理线程局部变量,从而提供线程安全的变量存储。它在多线程编程中非常有用,尤其是在必要确保线程独立性的场景中。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |