ThreadLocal在1.6版本中不是用一个全局的Map来存各个线程的变量副本,而是在Thread类中有一个ThreadLocalMap的变量,然后用Thread.currentThread().threadLocals.get(this)来引用的各线程变量副本,这样避免了去同步全局的Map
ThreadLocal使用的简单例子:
package com.test; public class TestNum { // ①通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值 private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() { public Integer initialValue() { return 0; } }; // ②获取下一个序列值 public int getNextNum() { seqNum.set(seqNum.get() + 1); return seqNum.get(); } public static void main(String[] args) { TestNum sn = new TestNum(); // ③ 3个线程共享sn,各自产生序列号 TestClient t1 = new TestClient(sn); TestClient t2 = new TestClient(sn); TestClient t3 = new TestClient(sn); t1.start(); t2.start(); t3.start(); } private static class TestClient extends Thread { private TestNum sn; public TestClient(TestNum sn) { this.sn = sn; } public void run() { for (int i = 0; i < 3; i++) { // ④每个线程打出3个序列值 System.out.println("thread[" + Thread.currentThread().getName() + "] --> sn[" + sn.getNextNum() + "]"); } } } }
通常我们通过匿名内部类的方式定义ThreadLocal的子类,提供初始的变量值,如例子中①处所示。TestClient线程产生一组序列号,在③处,我们生成3个TestClient,它们共享同一个TestNum实例。运行以上代码,在控制台上输出以下的结果:
thread[Thread-0] --> sn[1]
thread[Thread-1] --> sn[1]
thread[Thread-2] --> sn[1]
thread[Thread-1] --> sn[2]
thread[Thread-0] --> sn[2]
thread[Thread-1] --> sn[3]
thread[Thread-2] --> sn[2]
thread[Thread-0] --> sn[3]
thread[Thread-2] --> sn[3]
考察输出的结果信息,我们发现每个线程所产生的序号虽然都共享同一个TestNum实例,但它们并没有发生相互干扰的情况,而是各自产生独立的序列号,这是因为我们通过ThreadLocal为每一个线程提供了单独的副本。
上面例子中,是在自己的类中定义ThreadLocal,那么,那么,可否直接使用Thread.currentThread().threadLocals?
不可以的,因为threadLocals变量在Thread中时package的访问权限,只能在同一个包下访问。
但是可以通过反射来得到threadLocals中的内容,参考:
http://stackoverflow.com/questions/2001353/java-list-thread-locals
threadLocals 是干什么用的?
是线程存放多个ThreadLocal实例的。
ThreadLocal首先通过当前线程t得到threadLocals,然后把自身this作为key,从threadLocals中得到存储在线程本地的相关的数据
ThreadLocal中get 和set方法如下:
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
public T get() {
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();
}
其中 getMap方法简单如下:
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
总结ThreadLocal原理:ThreadLocal对象相当于线程私有财产(数据)的经纪人,为线程的私有财产(数据)提供存储和获取的功能
相关推荐
通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到spu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行...
C++11的标准类std::thread对线程进行了封装,定义了C++11标准中的一些表示线程的类、用于互斥访问的类与方法等。应用C++11中的std::thread便于多线程程序的移值。 std::thread类成员函数: (1)、get_id:获取线程ID...
thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread thread ...
Java并发编程---Thread类!!
通过 thread 类直接创建线程的 vb实例
分别用Thread类和Runnable接口实现的阶乘的计算过程及结果的显示(本来一开始设置的不要积分,不知道为啥变得需要积分了,故此调整一下)
在Java中创建线程有两种方法:使用Thread类和使用Runnable接口。在使用Runnable接口时需要建立一个Thread实例。因此,无论是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例。
一个简单的通过继承Thread类构造多线程实例,它的功能是模拟一个笼子内有20只鸟在里面移动,每个“鸟”是一个扩展的Thread类,它负责控制自身的移动。
本手册提供了有关ThreadX——Express Logic 公司高性能实时内核的详尽信息。 指南之意义 本手册适用于嵌入式实时软件的开发者。开发者应熟悉标准实时操作系统的功能及C 程序设计。 结构 手册包括七章,五个附录以及...
是第一次在C#中接触Thread,自己研究了一下其中Thread.Join()这个方法,下面谈谈自己的理解。 Thread.Join()在MSDN中的解释很模糊:Blocks the calling thread until a thread terminates 有两个主要问题: ...
ThreadX 中文手册,是学习ThreadX代码不可多得的中文参考资料,能帮你很快熟悉ThreadX系统架构。
雅特力的AT32F435/437,最高主频288MHZ,FLASH可以...项目中打开了2个线程,通过tx_mutex_get互斥操作,来输出print字符串到电脑串口调试助手。 项目完全从AT库里分离,独立成项目,很轻松就可以放到自己的项目里了。
用C++实现的具有跨平台兼容性的Thread类,是按照JAVA中Thread类的用法设计的,使用非常方便。仅供学习参考
请使用继承Thread类的方式定义两个线程,一个线程可以计算1--100所有数字的累加和,另一个线程可以计算1--1000所有数字的累加和,每个线程计算完毕后各自打印计算结果,格式例如:”xxx线程计算1--100的累加和,结果...
Thread类相对于线程池中的线程,使用者有更多的控制权。该类允许创建前台线程,设置线程优先级等。Thread类的构造函数重载为接受ThreadStart和ParameterizedThreadStart类型的委托参数。 1、给线程传递数据 给线程...
线程创建,线程等待与清除,thread_clean.c,thread_create.c,thread_create.c,thread_exit_struct.c,thread_id.c,thread_int.c, thread_join.c, thread_join.c, thread_string.c, thread_struct.c
继承Thread类: 1必须重写run 方法:里面放置的实际的线程体 2 启动线程: 3创建Thread对象 4调用Thread对象的start 方法启动线程
Thread类
赠送jar包:transmittable-thread-local-2.12.1.jar; 赠送原API文档:transmittable-thread-local-2.12.1-javadoc.jar;...人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。
首先看看boost::thread的构造函数吧,boost::thread有两个构造函数: (1)thread():构造一个表示当前执行线程的线程对象; (2)explicit thread(const boost::function0& threadfunc): boost::function0可以...