java threadlocal 实现_多线程-Java的ThreadLocal如何在后台实现?

假设您要实现ThreadLocal.ThreadLocalMap,如何使它特定于线程? 当然,最简单的方法是在Thread类中创建一个非静态字段,我们将其称为2540580664605405410305。由于每个线程均由一个线程实例表示,因此每个线程中的254058066460541010306也将有所不同。 这也是Java的作用:

/* ThreadLocal values pertaining to this thread. This map is maintained

* by the ThreadLocal class. */

ThreadLocal.ThreadLocalMap threadLocals = null;

ThreadLocal.ThreadLocalMap在这里是什么? 因为一个线程只有threadLocals,所以如果您简单地将threadLocals作为ThreadLocal(例如,将threadLocals定义为254058066460541010308),则一个特定线程只有254058066460541010309。 如果您想为一个线程使用多个ThreadLocal变量怎么办? 最简单的方法是将threadLocals设置为HashMap,每个条目的ThreadLocal313是ThreadLocal变量的名称,每个条目ThreadLocal315是ThreadLocal316变量的值。 有点困惑? 假设我们有两个线程t1和ThreadLocalMap,它们使用与25405806646221875875构造函数的参数相同的25405806646221875875实例,并且它们都有两个ThreadLocalMap变量,分别名为254058066462218752和HashMap和ThreadLocal。

t1.tlA

+-----+-------+

| Key | Value |

+-----+-------+

| tlA | 0 |

| tlB | 1 |

+-----+-------+

t2.tlB

+-----+-------+

| Key | Value |

+-----+-------+

| tlA | 2 |

| tlB | 3 |

+-----+-------+

请注意,这些值是由我组成的。

现在看来很完美。 但是ThreadLocalMap是什么? 为什么不只使用Entry class? 为了解决此问题,让我们看看通过2540580664622187587523类的WeakReference方法设置值时会发生什么:

public void set(T value) {

Thread t = Thread.currentThread();

ThreadLocalMap map = getMap(t);

if (map != null)

map.set(this, value);

else

createMap(t, value);

}

ThreadLocalMap仅返回Entry class。由于WeakReference已初始化为ThreadLocalMap,因此我们首先输入HashMap:

void createMap(Thread t, T firstValue) {

t.threadLocals = new ThreadLocalMap(this, firstValue);

}

它使用当前2540580664622187587521实例和要设置的值创建一个新的ThreadLocalMap实例。 让我们看看WeakReference是什么样的,它实际上是ThreadLocalMap类的一部分

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> {

/** The value associated with this ThreadLocal. */

Object value;

Entry(ThreadLocal> k, Object v) {

super(k);

value = v;

}

}

...

/**

* 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);

}

...

}

ThreadLocalMap类的核心部分是Entry class,它扩展了2540580664622187587522。它确保如果当前线程退出,将自动进行垃圾回收。 这就是为什么它使用ThreadLocalMap而不是简单的HashMap的原因。它将当前的25405806646221875875和它的值作为2540580664622187187526类的参数传递,因此当我们想要获取该值时,可以从2540580664622187187527(该实例的一个实例)中获取它。 Entry类别:

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();

}

这就是整个图片:

Dhws6.jpg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值