zoukankan      html  css  js  c++  java
  • 深入解析ThreadLocal类

    先了解一下ThreadLocal类提供的几个方法:

    public T get() { }
    public void set(T value) { }
    public void remove() { }
    protected T initialValue() { }  

    get()方法是用来获取ThreadLocal在当前线程中保存的变量副本,set()用来设置当前线程中变量的副本,remove()用来移除当前线程中变量的副本,initialValue()是一个protected方法,一般是用来在使用时进行重写的,它是一个延迟加载方法,下面会详细说明。

    首先我们来看一下ThreadLocal类是如何为每个线程创建一个变量的副本的。

         /**
         * Returns the value in the current thread's copy of this
         * thread-local variable.  If the variable has no value for the
         * current thread, it is first initialized to the value returned
         * by an invocation of the {@link #initialValue} method.
         *
         * @return the 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) {
                    @SuppressWarnings("unchecked")
                    T result = (T)e.value;
                    return result;
                }
            }
            return setInitialValue();
        }
    

    ThreadLocal类的一个内部类,我们继续取看ThreadLocalMap的实现

            static class ThreadLocalMap {
    
            /**
             * The entries in this hash map extend WeakReference, using
             * its main ref field as the key (which is always a
             * ThreadLocal object).  Note that null keys (i.e. entry.get()
             * == null) mean that the key is no longer referenced, so the
             * entry can be expunged from table.  Such entries are referred to
             * as "stale entries" in the code that follows.
             */
            static class Entry extends WeakReference<ThreadLocal<?>> {
                /** The value associated with this ThreadLocal. */
                Object value;
    
                Entry(ThreadLocal<?> k, Object v) {
                    super(k);
                    value = v;
                }
            }
    

      

    最常见的ThreadLocal使用场景为 用来解决 数据库连接、Session管理等。

    private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>() {
       public Connection initialValue() {
        return DriverManager.getConnection(DB_URL);
       }
    };
     
    public static Connection getConnection() {
       return connectionHolder.get();
    }
    
    private static final ThreadLocal threadSession = new ThreadLocal();
     
    public static Session getSession() throws InfrastructureException {
        Session s = (Session) threadSession.get();
        try {
            if (s == null) {
                s = getSessionFactory().openSession();
                threadSession.set(s);
            }
        } catch (HibernateException ex) {
            throw new InfrastructureException(ex);
        }
        return s;
    }
    

      

      

      

  • 相关阅读:
    CSU1090 数字转换问题[BFS+素数筛选]
    HDOJ2083 简易版之最短距离
    HOJ11525 Matchsticks
    HDOJ1058 Humble Numbers[DP]
    Sort函数进行升序和降序排列[#include <algorithm>]
    HDOJ1018 求N!的位数[斯特林公式处理阶乘及阶乘位数的问题]
    HDOJ1597 find the nth digit[一元二次方程求解]
    HOJ10641 Equidivisions [BFS]
    HOJ10814 Wooden Sticks[线性DP求最少不递增子序列+结构体排序]
    HOJ12363 Robots on a grid [DP+BFS()]
  • 原文地址:https://www.cnblogs.com/kaleidoscope/p/9877661.html
Copyright © 2011-2022 走看看