posts - 0, comments - 77, trackbacks - 0, articles - 356
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

ThreadLocal使用

Posted on 2008-04-24 09:32 semovy 阅读(960) 评论(0)  编辑  收藏 所属分类: JAVA基础
 TheadLocal包含了一组get(),set(Object)方法,可以获得当前线程的放进去的对象。

    ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。各个线程中访问的是不同的对象。

    另外,说ThreadLocal使得各线程能够保持各自独立的一个对象,这个对象的创建并不是通过ThreadLocal.set()来实现的,set()并不会做什么对象的拷贝,而是每个线程之前已经创建好的对象。通 过ThreadLocal.set()将这个新创建的对象的引用以当前线程为key,保存TheadLocal的一个map中,执行 ThreadLocal.get()时,各线程从map中取出以当前线程为key的对象,因此取出来的是各自自己线程中的对象。

 

下面来看看ThreadLocal的实现原理(jdk1.5源码)

代码
  1. public class ThreadLocal<T> {  
  2.     /**
  3.       * ThreadLocals rely on per-thread hash maps attached to each thread
  4.       * (Thread.threadLocals and inheritableThreadLocals).   The ThreadLocal
  5.       * objects act as keys, searched via threadLocalHashCode.   This is a
  6.       * custom hash code (useful only within ThreadLocalMaps) that eliminates
  7.       * collisions in the common case where consecutively constructed
  8.       * ThreadLocals are used by the same threads, while remaining well-behaved
  9.       * in less common cases.
  10.       */  
  11.     private final int threadLocalHashCode = nextHashCode();  
  12.   
  13.     /**
  14.       * The next hash code to be given out. Accessed only by like-named method.
  15.       */  
  16.     private static int nextHashCode = 0;  
  17.   
  18.     /**
  19.       * The difference between successively generated hash codes - turns
  20.       * implicit sequential thread-local IDs into near-optimally spread
  21.       * multiplicative hash values for power-of-two-sized tables.
  22.       */  
  23.     private static final int HASH_INCREMENT = 0x61c88647;  
  24.   
  25.     /**
  26.       * Compute the next hash code. The static synchronization used here
  27.       * should not be a performance bottleneck. When ThreadLocals are
  28.       * generated in different threads at a fast enough rate to regularly
  29.       * contend on this lock, memory contention is by far a more serious
  30.       * problem than lock contention.
  31.       */  
  32.     private static synchronized int nextHashCode() {  
  33.         int h = nextHashCode;  
  34.          nextHashCode = h + HASH_INCREMENT;  
  35.         return h;  
  36.      }  
  37.   
  38.     /**
  39.       * Creates a thread local variable.
  40.       */  
  41.     public ThreadLocal() {  
  42.      }  
  43.   
  44.     /**
  45.       * Returns the value in the current thread's copy of this thread-local
  46.       * variable.   Creates and initializes the copy if this is the first time
  47.       * the thread has called this method.
  48.       *
  49.       * @return the current thread's value of this thread-local
  50.       */  
  51.     public T get() {  
  52.          Thread t = Thread.currentThread();  
  53.          ThreadLocalMap map = getMap(t);  
  54.         if (map != null)  
  55.             return (T)map.get(this);  
  56.   
  57.         // Maps are constructed lazily.   if the map for this thread  
  58.         // doesn't exist, create it, with this ThreadLocal and its  
  59.         // initial value as its only entry.  
  60.          T value = initialValue();  
  61.          createMap(t, value);  
  62.         return value;  
  63.      }  
  64.   
  65.     /**
  66.       * Sets the current thread's copy of this thread-local variable
  67.       * to the specified value.   Many applications will have no need for
  68.       * this functionality, relying solely on the {@link #initialValue}
  69.       * method to set the values of thread-locals.
  70.       *
  71.       * @param value the value to be stored in the current threads' copy of
  72.       *         this thread-local.
  73.       */  
  74.     public void set(T value) {  
  75.          Thread t = Thread.currentThread();  
  76.          ThreadLocalMap map = getMap(t);  
  77.         if (map != null)  
  78.              map.set(this, value);  
  79.         else  
  80.              createMap(t, value);  
  81.      }  
  82.   
  83.     /**
  84.       * Get the map associated with a ThreadLocal. Overridden in
  85.       * InheritableThreadLocal.
  86.       *
  87.       * @param   t the current thread
  88.       * @return the map
  89.       */  
  90.      ThreadLocalMap getMap(Thread t) {  
  91.         return t.threadLocals;  
  92.      }  
  93.   
  94.     /**
  95.       * Create the map associated with a ThreadLocal. Overridden in
  96.       * InheritableThreadLocal.
  97.       *
  98.       * @param t the current thread
  99.       * @param firstValue value for the initial entry of the map
  100.       * @param map the map to store.
  101.       */  
  102.     void createMap(Thread t, T firstValue) {  
  103.          t.threadLocals = new ThreadLocalMap(this, firstValue);  
  104.      }  
  105.   
  106.      .......  
  107.   
  108.     /**
  109.       * ThreadLocalMap is a customized hash map suitable only for
  110.       * maintaining thread local values. No operations are exported
  111.       * outside of the ThreadLocal class. The class is package private to
  112.       * allow declaration of fields in class Thread.   To help deal with
  113.       * very large and long-lived usages, the hash table entries use
  114.       * WeakReferences for keys. However, since reference queues are not
  115.       * used, stale entries are guaranteed to be removed only when
  116.       * the table starts running out of space.
  117.       */  
  118.     static class ThreadLocalMap {  
  119.   
  120.      ........  
  121.   
  122.      }

以hibernate中典型的ThreadLocal的应用:
代码
  1. private static final ThreadLocal threadSession = new ThreadLocal();  
  2.   
  3. public static Session getSession() throws InfrastructureException {  
  4.      Session s = (Session) threadSession.get();  
  5.     try {  
  6.         if (s == null) {
  7.           //每一个线程第一次使用getSession都会到这,调用openSession。
  8.              s = getSessionFactory().openSession();  
  9.              threadSession.set(s);  
  10.          }  
  11.      } catch (HibernateException ex) {  
  12.         throw new InfrastructureException(ex);  
  13.      }  
  14.     return s;  
  15. }

只有注册用户登录后才能发表评论。


网站导航: