java.lang.ThreadLocal源码分析
ThreadLocal类提供线程本地变量,为变量在每个线程创建一个副本,每个线程可以访问自己内部的副本变量。
比如,有这样一个需求,需要为每个线程创建一个独一无二的标识,这个标识在第一次调用ThreadId.get()的时候生成,在随后的调用中不会再改变。
public class ThreadId {
private static final AtomicInteger nextId = new AtomicInteger(0);
private static final ThreadLocal<Integer> threadId =
new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return nextId.getAndIncrement();
}
};
public static int get() {
return threadId.get();
}
}
类声明:
public class ThreadLocal<T> {}
实例变量和相关的一个方法:
//用于ThreadLocalMap
private final int threadLocalHashCode = nextHashCode(); //下一个hash code,从0开始
private static AtomicInteger nextHashCode = new AtomicInteger(); //hash增量
private static final int HASH_INCREMENT = 0x61c88647; //在获取下一个hash code
private static int nextHashCode() {
return nextHashCode.getAndAdd(HASH_INCREMENT);
}
构造方法:
public ThreadLocal() {}
重要的操作:
//线程本地变量的初始化方法,访问修饰符为protected是为了让程序员可以覆盖这个方法,默认是返回null,也就是说默认的线程本地变量值为null
protected T initialValue() {
return null;
}
get操作
//获取当前线程的本地变量
public T get() {
Thread t = Thread.currentThread();//得到当前的线程
ThreadLocalMap map = getMap(t);//根据当前线程获得一个ThreadLocalMap
if (map != null) {//如果不为空
ThreadLocalMap.Entry e = map.getEntry(this);//根据当前对象获得Entry
if (e != null) {//如果本地变量存在,返回值
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
//否则调用setInitialValue方法
return setInitialValue();
}
getMap方法
//返回当前线程的threadLocals变量
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
threadLocals的声明
//其实就是一个ThreadLocalMap类型的变量
ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocalMap
//ThreadLocalMap里有Entry内部类,用于存放键值对
static class ThreadLocalMap {
static class Entry extends WeakReference<ThreadLocal<?>> {
Object value; Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
.....以下省略
}
setInitialValue方法
private T setInitialValue() {
T value = initialValue();//调用initialValue方法,初始化本地变量的值,如果不覆盖该方法,返回null
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);//根据当前线程获取ThreadLocalMap
if (map != null)//如果map不为空
map.set(this, value);//设置键值对
else
createMap(t, value);//否则创建map
return value;
}
createMap方法
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
至此可以知道ThreadLocal如何为每个线程创建变量副本了,每个线程Thread内部有一个ThreadLocal.ThreadLocalMap类型的成员变量threadLocals,这个threadLocals就是用来存储实际的变量副本的,存储以ThreadLocal为键,本地线程变量为值的键值对。
remove操作
//先获取当前线程的ThreadLocalMap,然后删除当前ThreadLocal对象
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
java.lang.ThreadLocal源码分析的更多相关文章
- 【JAVA】ThreadLocal源码分析
ThreadLocal内部是用一张哈希表来存储: static class ThreadLocalMap { static class Entry extends WeakReference<T ...
- java.lang.StringBuffer源码分析
StringBuffer是一个线程安全的可变序列的字符数组对象,它与StringBuilder一样,继承父类AbstractStringBuilder.在多线程环境中,当方法操作是必须被同步,Stri ...
- java.lang.StringBuilder源码分析
StringBuilder是一个可变序列的字符数组对象,它继承自AbstractStringBuilder抽象类.它不保证同步,设计出来的目的是当这个字符串缓存只有单线程使用的时候,取代StringB ...
- java.lang.Runnable 源码分析
子接口:RunnableFuture<V>, RunnableScheduledFuture<V> 实现类:AsyncBoxView.ChildState, ForkJoinW ...
- Java并发编程之ThreadLocal源码分析
## 1 一句话概括ThreadLocal<font face="微软雅黑" size=4> 什么是ThreadLocal?顾名思义:线程本地变量,它为每个使用该对象 ...
- Java多线程学习之ThreadLocal源码分析
0.概述 ThreadLocal,即线程本地变量,是一个以ThreadLocal对象为键.任意对象为值的存储结构.它可以将变量绑定到特定的线程上,使每个线程都拥有改变量的一个拷贝,各线程相同变量间互不 ...
- ThreadLocal源码分析-黄金分割数的使用
前提 最近接触到的一个项目要兼容新老系统,最终采用了ThreadLocal(实际上用的是InheritableThreadLocal)用于在子线程获取父线程中共享的变量.问题是解决了,但是后来发现对T ...
- 并发编程(四)—— ThreadLocal源码分析及内存泄露预防
今天我们一起探讨下ThreadLocal的实现原理和源码分析.首先,本文先谈一下对ThreadLocal的理解,然后根据ThreadLocal类的源码分析了其实现原理和使用需要注意的地方,最后给出了两 ...
- 并发-ThreadLocal源码分析
ThreadLocal源码分析 参考: http://www.cnblogs.com/dolphin0520/p/3920407.html https://www.cnblogs.com/coshah ...
随机推荐
- 在Shell中使用函数文件
需要编写一个较庞大的脚本时,可能会涉及许多函数.变量.这是通常建议将众多的函数.变量放入一个单独的脚本内.这样做的好处很明显,不用担心某个函数.变量是否已经被定义和使用,也不用频繁地定义.清除函数和变 ...
- C# mvc--EF中查询的本质
UI层我直接用了窗体程序. 好了 不罗嗦 直接上代码…… private void button1_Click(object sender, EventArgs e) { //1.0创建EF上下文容器 ...
- EF——一对一、一对多、多对多关系的配置和级联删除 04(转)
EF里一对一.一对多.多对多关系的配置和级联删除 本章节开始了解EF的各种关系.如果你对EF里实体间的各种关系还不是很熟悉,可以看看我的思路,能帮你更快的理解. I.实体间一对一的关系 添加一个P ...
- 【源码】基于SQLite实现CMS论坛(BBS)----附件SQLite可视化界面客户端
使用说明:管理员账号:admin 密码:523523523 一. 账号管理(登陆注册审核) 1.账号注册 url:/BBS/Account/pregister.aspx 2 ...
- The calculation of GPA
Problem Description 每学期的期末,大家都会忙于计算自己的平均成绩,这个成绩对于评奖学金是直接有关的.国外大学都是计算GPA(grade point average) 又称GPR(g ...
- Spring MVC Controller单例陷阱
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://lavasoft.blog.51cto.com/62575/1394669 Spr ...
- TextRank算法提取关键词的Java实现
转载:码农场 » TextRank算法提取关键词的Java实现 谈起自动摘要算法,常见的并且最易实现的当属TF-IDF,但是感觉TF-IDF效果一般,不如TextRank好. TextRank是在 G ...
- IOS开发UI篇之自动滚动图片
我们在做项目是有时候会遇到设置自动滚动图片,所以我自己也遇到过两次.觉得他是一个挺有意思东西,所以做了下总结 DEMO: .h #import <UIKit/UIKit.h> @inter ...
- 实用技术——Eclipse 常用快捷键
Eclipse的编辑功能非常强大,掌握了Eclipse快捷键功能,能够大大提高开发效率. 和编辑相关的快捷键 Eclipse中有如下一些和编辑相关的快捷键. 1. [ALT+/] 此快捷键为用户编 ...
- linux_cpu信息查询
查看cpu信息: [root@css-management ~]# cat /proc/cpuinfo processor : 0vendor_id : GenuineIntelcpu family ...