-- 最近再探Spring,深入研究了一下Spring的Introduce Advice。其中涉及到了关于ThreadLocal的一些内容,回顾了一下,这里做个记录。
-- Java DOC说ThreadLocal存储了一个线程的局部变量,内部究竟是怎样的。具体如下:
-- Thread中维护了一个ThreadLocal.ThreadLocalMap的变量。
ThreadLocal.ThreadLocalMap threadLocals = null;
-- 当我们调用ThreadLocal的set方法的时候,实际上是往Thread.currentThread()也就是当前线程的ThreadLocalMap变量中添加数据。
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
-- 由此可见,一个Thread可以维护多个ThreadLocal
-- 再看ThreadLocal.ThreadLocalMap(ThreadLocalMap是ThreadLocal的静态内部类,为了方便,下面简写为ThreadLocalMap)
ThreadLocalMap是不是像他名字所写的那样使用了一个Map来储存一个Thread的局部变量呢?答案是否定的。
private Entry[] table;
实际上它用的是一个ThreadLocalMap.Entry数组。这个数组的初始容量为16.
private static final int INITIAL_CAPACITY = 16;
-- Entry是ThreadLocalMap静态内部类。下面简写为Entry。
-- 那么又是如何往Entry[ ]中添加数据呢?
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();
}
-- 这里使用了ThreadLocal的threadLocalHashCode与16进制的F做与操作的结果作为索引来向Entry数组添加数据。上面判断是否已经使用当前TheadLocal添加了数据,下面对数组越界做处理。具体怎么处理的,时间所限没有深究。
-- 至于Entry本质上就是一个没有存取器的Java Bean。它有两个属性:
ThreadLocal类型的key,
Object类型的Value
分享到:
相关推荐
Thread currentThread=Thread.currentThread(); Object o=valueMap.get(currentThread);//返回本线程对应的变量 if(o==null&&!valueMap.containsKey(currentThread)){ //如果在 Map 中不存在,放到 Map 中保存...
Thread currentThread = Thread.currentThread(); T o = valueMap.get(currentThread); if (o == null && !valueMap.containsKey(currentThread)) { o = initialValue(); valueMap.put(currentThread, o); } ...
System.out.println(Thread.currentThread().getName() + "====" + threadLocal.get()); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } finally { threadLocal...
#### 一、ThreadLocal简介与重要性 ThreadLocal是一个非常重要的Java并发工具类,它的核心概念在于为每一个线程提供了一个独立的变量副本,从而避免了线程之间的数据竞争问题。这使得每个线程在访问ThreadLocal变量...
System.out.println("Current Thread: " + Thread.currentThread().getName() + ", Value: " + threadLocal.get()); } } ``` 这个简单的例子展示了两个线程分别设置并打印ThreadLocal变量,它们不会相互影响。 ...
在例子中,使用了HashMap来存储每个线程的数据,通过Thread.currentThread()作为键来存取数据。这样每个线程都有自己的数据副本,实现了线程内的数据独立,避免了线程之间的数据冲突。但是,这种方式并不保证线程...
System.out.println("Thread[" + Thread.currentThread().getName() + "] sn[" + sn.getNextNum() + "]"); } } } public static void main(String[] args) { SequenceNumber seqNum = new SequenceNumber(); ...
通过ThreadLocal对象定位到线程:Thread.currentThread()通过ThreadLocal对象拿到所在的ThreadLocalMap: T
在Java中,我们可以使用`Thread.currentThread().getId()`来获取当前线程的ID。这个ID是一个长整型(`long`)值,每次创建新的线程时,都会分配一个新的ID。例如: ```java public class ThreadIdExample { ...
- 在`ThreadLocal`的`get()`方法中,首先通过`Thread.currentThread().threadLocals`获取到当前线程的`ThreadLocalMap`,然后根据`this`(即当前的ThreadLocal实例)作为键查找值。 - `set()`方法中,首先检查`...
1. **获取线程局部变量**:当线程试图获取线程局部变量的值时,首先会通过`Thread.currentThread()`获取当前线程。然后,通过当前线程获取对应的`ThreadLocalMap`实例,并基于`ThreadLocal`对象作为键查找对应的值。...
response.getWriter().println("The current thread served this servlet " + counter.getCount() + " times"); counter.increment(); // 添加以下代码来清除 ThreadLocal 中的引用 myThreadLocal.remove(); } ...
TextMessage msg = session.createTextMessage(Thread.currentThread().getName()+ "productor:我是大帅哥,我现在正在生产东西!,count:"+num); System.out.println(Thread.currentThread().getName()+ ...
Thread currentThread = Thread.currentThread(); T o = valueMap.get(currentThread); if (o == null && !valueMap.containsKey(currentThread)) { o = initialValue(); valueMap.put(currentThread, o); } ...
在ThreadLocal的set方法中,首先获取当前执行代码的线程对象(Thread t = Thread.currentThread();),然后尝试获取或创建该线程的ThreadLocalMap(ThreadLocalMap map = getMap(t);)。如果当前线程还没有...
3. 如果当前线程尚未创建`ThreadLocal.Values`实例,那么会通过`initializeValues(currentThread)`方法初始化一个新的实例。 4. 最后,调用`put`方法将`ThreadLocal`对象(这里的`this`)和要存储的值(`value`)放...
使用`Thread.CurrentThread`属性可以获取当前线程的状态。 3. **线程优先级** - 每个线程都有一个优先级,可以使用`Priority`属性设置。优先级有四种:最低(Lowest)、低于正常(BelowNormal)、正常(Normal)、...
Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) return (T)e.value; } return setInitialValue();...