Java多线程ThreadLocal

关于ThreadLocal,java中有一个很相似的对比机制:clone.

他们的思想都是,给当前的线程/方法一个本地变量的copy,各个线程/方法虽然看起来是共享了一个变量,但相互之间并不干扰交互。

ThreadLocal是非常轻量级的保证线程安全的机制,不涉及锁,不涉及同步阻塞。完全是线程内部的一个变量。

那有的同学可能会问,既然这样干嘛还要设计成类的成员变量,直接在方法里面声明然后在方法之间传递不就好了。这样其实完全可以,但是相对来说代码结构会更加复杂,不利于后期的维护,我们来看一个ThreadLocal的例子:


  1. public class ConnectionManager {  
  2.   
  3.     /** 线程内共享Connection,ThreadLocal通常是全局的,支持泛型 */  
  4.     private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();  
  5.       
  6.     public static Connection getCurrConnection() {  
  7.         // 获取当前线程内共享的Connection  
  8.         Connection conn = threadLocal.get();  
  9.         try {  
  10.             // 判断连接是否可用  
  11.             if(conn == null || conn.isClosed()) {  
  12.                 // code : 创建新的Connection赋值给conn  
  13.                 // code : 保存Connection  
  14.                 threadLocal.set(conn);  
  15.             }  
  16.         } catch (SQLException e) {  
  17.         }  
  18.         return conn;  
  19.     }  
  20.       
  21.     /** 
  22.      * 关闭当前数据库连接 
  23.      */  
  24.     public static void close() {  
  25.         // 获取当前线程内共享的Connection  
  26.         Connection conn = threadLocal.get();  
  27.         try {  
  28.             // 判断是否已经关闭  
  29.             if(conn != null && !conn.isClosed()) {  
  30.                 // 关闭资源  
  31.                 conn.close();  
  32.                 // 移除Connection  
  33.                 threadLocal.remove();  
  34.                 conn = null;  
  35.             }  
  36.         } catch (SQLException e) {  
  37.             // 异常处理  
  38.         }  
  39.     }  
  40. }  

这是ThreadLocal应用的一个典型场景,大家可以琢磨一下两个问题:

1.如果不用ThreadLocal会怎么样?

2.如果不用ThreadLocal该怎么做?


如果最后你觉得在这种场景下ThreadLocal是最好的选择那么你基本就理解了ThreadLocal和它的使用场景。


接下来看一下Threadlocal的内部实现原理。

如果看过Thread和ThreadLocal源码的同学会发现,在Thread类内部有一个ThreadLocal.ThreadLocalMap这样的一个成员变量。在调用ThreadLocal的set/get时,程序会根据当前线程来获取对应的ThreadLocalMap,即Thread对象的ThreadLocal.ThreadLocalMap这个表,然后把值放入该Map中,即这个值是在线程内部而非ThreadLocal内部。这样在一个Thread对象里可以存放多个TheadLocal对象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章