`

关于 ThreadLocal

 
阅读更多

                     ThreadLocal总结 
一、 ThreadLocal简介 
ThreadLocal并不能从命名上理解为线程的本地实现版本,因为它并不是一个线程,而是ThreadLocal Variable(线程局部变量)。它的功能非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,使得每一个线程都可以独立地改变自己的副本,而不会和其他线程珠副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。

在线程是活动并且ThreadLocal对象是可访问时,该线程就持有一个到该线程局部变量副本的隐含引用。当该线程运行结束后,该线程拥有的所有线程局部变量的副本都将失效,并等待垃圾收集器收集。 


二、 ThreadLocal原理 
1. 每个线程中都有一个自己的ThreadLocalMap类对象,可以将线程自己的对象保持到其中,各管各的,线程可以正确的访问到自己的对象。比如起了十个线程,十个线程里面ThreadLoacl里面放的东西是不会共享(相互干扰),线程安全 
2. 如果ThreadLocal.set()进去的东西本来就是多个线程共享的同一个对象,那么多个线程的ThreadLocal.get()取得的还是这个共享对象本身,还是有并发访问问题。 
3. ThreadLocal只能充当当前线程的Context,线程结束,当前线程中存放的变量也被销毁了,同时我们每次使用完ThreadLocal后,要记得把里面的变量清空。  
4. Thread里面保存了个Map,threadLocal是个map entry key。ThreadLocal的实现决定了这ThreadLocal类的所有的对象,它们的key都不一样,所以可以用来做map entry key。 
5. 那么thread local的数据在哪里呢?在Thread对象里,而并不是存放在ThreadLocal中,ThreadLocal只是提供了操作。源码: 

public void set(T value) { 
        Thread t = Thread.currentThread(); 
        ThreadLocalMap map = getMap(t); 
        if (map != null) 
            map.set(this, value); 
        else 
            createMap(t, value); 
    } 

 
   注意:ThreadLocalMap的实例是存放在Thread对象中的 
   ThreadLocal.ThreadLocalMap threadLocals = null; 
而ThreadLocalMap只是ThreadLocal中的一个静态内部类。 
三、 ThreadLocal作用 
1、 通过ThreadLocal方式封装数据库Connection(省略Web、Service层) 
 

伪代码如下:

/** 
* 使用ThreadLocal封装Conection 
* @author junxy 
* 
*/ 
public class ConnectionManager { 

private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>(); 
/** 
* 获取数据库链接 
* @return conn 
*/ 
public static Connection getConn(){ 
Connection conn = connectionHolder.get(); 
if(conn==null){ 
//1.获取数据库链接 
//2.设置到ThreadLocal中 
connectionHolder.set(conn); 
} 
return conn; 
} 
/** 
* 关闭数据库链接 
*/ 
public static void closeConn(){ 
Connection conn = connectionHolder.get(); 
if(conn!=null){ 
//1.关闭数据库练级 
//2.清空ThreadLocal中链接  切记! 
connectionHolder.remove(); 
} 
} 
} 

 
2、多线程环境下共享资源的传递 

    

    转: http://lifenotes.iteye.com/blog/827223

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics