欢迎来到天天文库
浏览记录
ID:15598041
大小:43.00 KB
页数:7页
时间:2018-08-04
《java多线程-threadlocal的设计与使用》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库。
1、ThreadLocal是什么 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。线程局部变量并不是
2、Java的新发明,在其它的一些语言编译器实现(如IBMXLFORTRAN)中,它在语言的层次提供了直接的支持。因为Java中没有提供在语言层次的直接支持,而是提供了一个ThreadLocal的类来提供支持,所以,在Java中编写线程局部变量的代码相对比较笨拙,这也许是线程局部变量没有在Java中得到很好的普及的一个原因吧。 ThreadLocal的设计 首先看看ThreadLocal的接口: Objectget();//返回当前线程的线程局部变量副本protectedObjectinitial
3、Value();//返回该线程局部变量的当前线程的初始值voidset(Objectvalue);//设置当前线程的线程局部变量副本的值 ThreadLocal有3个方法,其中值得注意的是initialValue(),该方法是一个protected的方法,显然是为了子类重写而特意实现的。该方法返回当前线程在该线程局部变量的初始值,这个方法是一个延迟调用方法,在一个线程第1次调用get()或者set(Object)时才执行,并且仅执行1次。ThreadLocal中的确实实现直接返回一个null:pr
4、otectedObjectinitialValue(){returnnull;} ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。比如下面的示例实现:publicclassThreadLocal{ privateMapvalues=Collections.synchronizedMap(newHashMap()); publicObjectget() { ThreadcurThread
5、=Thread.currentThread(); Objecto=values.get(curThread); if(o==null&&!values.containsKey(curThread)) { o=initialValue(); values.put(curThread,o); } returno; } publicvoidset(ObjectnewValue) { values.put(Thread.currentThread(),newValue); } publi
6、cObjectinitialValue() { returnnull; }} 当然,这并不是一个工业强度的实现,但JDK中的ThreadLocal的实现总体思路也类似于此。 ThreadLocal的使用 如果希望线程局部变量初始化其它值,那么需要自己实现ThreadLocal的子类并重写该方法,通常使用一个内部匿名类对ThreadLocal进行子类化,比如下面的例子,SerialNum类为每一个类分配一个序号:publicclassSerialNum{ //Thenextserialnumb
7、ertobeassigned privatestaticintnextSerialNum=0; privatestaticThreadLocalserialNum=newThreadLocal() { protectedsynchronizedObjectinitialValue() { returnnewInteger(nextSerialNum++); } }; publicstaticintget() { return((Integer)(serialNum.get())).int
8、Value(); }} SerialNum类的使用将非常地简单,因为get()方法是static的,所以在需要获取当前线程的序号时,简单地调用:intserial=SerialNum.get(); 即可。 在线程是活动的并且ThreadLocal对象是可访问的时,该线程就持有一个到该线程局部变量副本的隐含引用,当该线程运行结束后,该线程拥有的所以线程局部变量的副本都将失效,并等待垃圾收集器收集。Thread-SpecificStoragepattern假设有一个
此文档下载收益归作者所有