ThreadLocal的用法与源码分析
来源:互联网 发布:科比81数据 编辑:程序博客网 时间:2024/05/05 11:35
目 录:
深入理解ThreadLocal
ThreadLocal的基本用法
ThreadLocal源码分析
ThreadLocal使用场景
使用ThreadLocal应注意什么
一:深入理解ThreadLocal
ThreadLocal,很多地方叫做线程本地变量,也有些地方叫做线程本地存储,其实意思差不多。可能很多朋友都知道ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。
ThreadLocal 位于java.lang包下, 该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
二:ThreadLocal的基本用法
ThreadLocal包含4个基本方法: get()、set()、initialValue()、remove() ;
T
get() 返回此线程局部变量的当前线程副本中的值。
protected T
initialValue() 返回此线程局部变量的当前线程的“初始值”。
void
remove() 移除此线程局部变量当前线程的值。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
void
set(T value) 将此线程局部变量的当前线程副本中的值设置为指定值。
三:ThreadLocal的源码分析
/**
* Returns the value in the current thread's copy of this
* thread-local variable. If the variable has no value for the
* current thread, it is first initialized to the value returned
* by an invocation of the {@link #initialValue} method.
*
* @return the current thread's value of this thread-local
*/
public T get() {
Thread t = Thread.currentThread(); //得到当前线程
ThreadLocalMap map = getMap(t); //获取当前线程相关的ThreadLocalMap
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this); //
if (e != null)
return (T)e.value;
}
return setInitialValue(); //如果获取不到当前线程相关ThreadLocalMap对象,则调用“初始值”方法。开发者可重写initialValue();
}
获取一个和当前线程相关的ThreadLocalMap
/**
* Get the map associated with a ThreadLocal. Overridden in
* InheritableThreadLocal.
*
* @param t the current thread
* @return the map
*/
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
/**
* Sets the current thread's copy of this thread-local variable
* to the specified value. Most subclasses will have no need to
* override this method, relying solely on the {@link #initialValue}
* method to set the values of thread-locals.
*
* @param value the value to be stored in the current thread's copy of
* this thread-local.
*/
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value); //将该变量赋值到ThreadLocal对象。
else
createMap(t, value); //如果该ThreaLocal为空,则创建该对象并赋值该变量
}
创建ThreadLocal对象
/**
* Create the map associated with a ThreadLocal. Overridden in
* InheritableThreadLocal.
*
* @param t the current thread
* @param firstValue value for the initial entry of the map
* @param map the map to store.
*/
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
setInitialValue() 方法 ,这里很容易理解
/**
* Variant of set() to establish initialValue. Used instead
* of set() in case user has overridden the set() method.
*
* @return the initial value
*/
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;
}
// remove方法
public void remove() { ThreadLocalMap localThreadLocalMap = getMap(Thread.currentThread()); if (localThreadLocalMap != null) localThreadLocalMap.remove(this); }
四:ThreadLocal的使用场景
ThreadLocal是隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源(变量),这样当然不需要对多个线程进行同步了。如果你需要进行多个线程之间进行通信,则使用同步机制;如果需要隔离多个线程之间的共享冲突,就可以使用ThreadLocal。
五:使用ThreadLocal 应注意什么
1.使用ThreadLocal时,应先使用set方法对其"赋值"操作,如果未先进行赋值,会报空指针异常(如果未重写initialValue()方法)。或者重写initialValue()方法!
2.使用完ThreadLocal后,建议调用remove()通知GC回收该对象,勿直接将ThreadLocal置为null,否则可能导致OutOfMemoryError异常。
3.还有一点就是,ThreadLocalMap存储的键值对中的键是this对象指向的ThreadLocal对象,而值就是你所设置的对象了。
0 0
- ThreadLocal的用法与源码分析
- ThreadLocal 的用法与分析
- ThreadLocal类的用法与源码解析
- ThreadLocal的源码分析
- ThreadLocal的源码分析
- ThreadLocal与WeakReference 源码分析
- ThreadLocal原理与源码分析
- ThreadLocal类详解与源码分析
- Threadlocal 源码分析与内存泄漏
- ThreadLocal源码分析与使用场景
- ThreadLocal与Synchronized的用法
- ThreadLocal与Synchronized的用法
- ThreadLocal与Synchronized的用法
- ThreadLocal与Synchronized的用法
- ThreadLocal与Synchronized的用法
- ThreadLocal与synchronized的分析
- ThreadLocal的分析与使用
- ThreadLocal的研究_源码分析
- 噩梦系列篇之Player受伤功能及伤害效果
- 北京市地铁线路及站点数据
- java内存分配和String类型的深度解析
- 【转载】ResultSet、ResultSetMetaData 用法详细说明
- 刚开始玩linux ,安装的CentOS连不上网络,原来是它的原因,小样,干不死你
- ThreadLocal的用法与源码分析
- java 实用方法
- Observer android.support.v4.view.ViewPager$PagerObserver@431a27a0 was not registered.
- eclipse风格主题调优
- Mustache 使用心得总结
- 观察者模式
- android 浮层简单实现、activity设置Theme
- iOS 获取文件大小fileSize && 文件删除
- 数组 Merge Sorted Array