Java---ThreadLocal的用法与理解实现
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java---ThreadLocal的用法与理解实现,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4138字,纯文字阅读大概需要6分钟。
内容图文
java.lang 类 ThreadLocal<T>
我们可以称ThreadLocal为:线程本地变量
官方API是这样介绍的:
该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。
我们直接new 就可以构造一个 ThreadLocal对象。
它只有4个方法:
T get()
返回此线程局部变量的当前线程副本中的值。
protected T initialValue()
返回此线程局部变量的当前线程的“初始值”。
voidremove()
移除此线程局部变量当前线程的值。
voidset(T value)
将此线程局部变量的当前线程副本中的值设置为指定值。
initialValue这个方法是一个延迟调用方法(可以理解成给初始值),在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。
如果程序员希望线程局部变量具有 null 以外的值,则必须为 ThreadLocal 创建子类,并重写此方法。通常将使用匿名内部类完成此操作。
通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值
privatestatic ThreadLocal t= new ThreadLocal(){
public Integer initialValue() {
return0;
}
};
ThreadLocal是这样做到为每一个线程维护变量的:
在ThreadLocal类中有一个Map<Thread,Object>,
用于存储每一个线程与线程变量的值,Map中元素的键为线程对象,而值对应线程的变量值。
我们自己就可以写出一个简单的实现版本:
package cn.hncu;
import java.util.HashMap;
import java.util.Map;
public class MyThreadLocle {
privateMap<Thread, Object>map=new HashMap<Thread, Object>();
public Object get(){
Thread curThread =Thread.currentThread();
Object value =map.get(curThread);
return value;
}
publicvoidset(Object obj){
Thread curThread =Thread.currentThread();
map.put(curThread, obj);
}
}
现在我们用一个实例来加深对ThreadLocal的理解:
package cn.hncu;
import java.util.Random;
import org.junit.Test;
publicclass ThreadLocalDemo {
privatestatic ThreadLocal<Object> t1 = new ThreadLocal<Object>();
publicstatic Object getValue(){
Object o = t1.get();
//不用给key,因为t1内部会自动获取当前线程的thread对象,并以上作为key到它的池中去取objif(o==null){
System.out.println("空的");
Random r = new Random();
o = r.nextInt(1000);
t1.set(o);
}
return o;
}
@Test
publicvoidtest(){
Object obj = getValue();
Object obj2 = getValue();//第二次去拿,不是空的了
System.out.println(obj+","+obj2);
System.out.println(obj==obj2);//true
A a = new A();
Object obj3 = a.getValue();
System.out.println(obj==obj3);//true
B b = new B();
final Object obj4 = b.getValue();
System.out.println(obj3==obj4);//true//由上面的例子可以知道,只要是同一个线程,不管是哪个类,从ThreadLocal中get的对象都是同一个
System.out.println("---====不同的线程====---");
new Thread() {
@Override
publicvoidrun() {
A a = new A();
Object obj5 = a.getValue();
System.out.println("obj5:"+obj5);
B b = new B();
Object obj6 = b.getValue();
System.out.println("obj6:"+obj6);
System.out.println("obj5=obj6:"+(obj5==obj6));
System.out.println("obj4=obj5:"+(obj4==obj5));
}
}.start();
}
}
class A{
public Object getValue(){
Object obj = ThreadLocalDemo.getValue();
System.out.println("A:"+obj);
return obj;
}
}
class B{
public Object getValue(){
Object obj = ThreadLocalDemo.getValue();
System.out.println("B:"+obj);
return obj;
}
}
通过上面那个实例我们可以知道:
各个线程中访问的是不同的对象。
通过ThreadLocal.set()将这个新创建的对象的引用保存到各线程的自己的一个map中,每个线程都有这样一个map,执行ThreadLocal.get()时,各线程从自己的map中取出放进去的对象,因此取出来的是各自自己线程中的对象,ThreadLocal实例是作为map的key来使用的。
看下jdk1.7的部分ThreadLocal类源码:
get()与set()方法:
/**
* Returns the value inthe current thread‘s copyof this
* thread-local variable. If the variable has no value forthe
* current thread, itisfirst initialized tothe value returned
* by an invocation ofthe {@link #initialValue} method.
*
* @returnthe current thread‘s value of this thread-local
*/
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();
}
/**
* Sets the current thread‘s copyof this thread-local variable
* tothe specified value. Most subclasses will have no need to
* override this method, relying solely onthe {@link #initialValue}
* method tosetthe values of thread-locals.
*
* @param value the value to be stored inthe current thread‘s copyof
* this thread-local.
*/
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
原文:http://blog.csdn.net/qq_26525215/article/details/52204097
内容总结
以上是互联网集市为您收集整理的Java---ThreadLocal的用法与理解实现全部内容,希望文章能够帮你解决Java---ThreadLocal的用法与理解实现所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。