ThreadLocal的底层实现原理与应用场景

来源:互联网 发布:spss20是什么软件 编辑:程序博客网 时间:2024/06/09 20:15

维持线程封闭性的一种规范方法是使用ThreadLocal。它提供了set和get等访问方法,这些方法为每个使用该变量的线程都存有一份独立的副本,因此get方法总是返回由当前执行线程在调用set时设置的最新值。那么,我们就看看关于这两个方法的JDK源码:

 public void set(T value) {        Thread t = Thread.currentThread();        ThreadLocalMap map = getMap(t);        if (map != null)            map.set(this, value);        else            createMap(t, value);    }
  public T get() {        Thread t = Thread.currentThread();        ThreadLocalMap map = getMap(t);        if (map != null) {            ThreadLocalMap.Entry e = map.getEntry(this);            if (e != null) {                T result = (T)e.value;                return result;            }        }        return setInitialValue();    }

用文字描述就是:get方法里通过Thread.currentThread()获取当前执行的线程,该方法内部包含一个ThreadLocalMap对象,针对每个thread保留一个entry,该entry的值就是当前线程保留的一个变量副本。


应用场景:ThreadLocal对象通常用于防止对可变的单实例变量或全局变量进行共享。例如,由于JDBC的连接对象不是线程安全的,因此,当多线程应用程序在没有协同的情况下,使用全局变量时,就不是线程安全的。通过将JDBC的连接对象保存到ThreadLocal中,每个线程都会拥有属于自己的连接对象副本。

使用方法:

1、在多线程的类(如ThreadDemo类)中,创建一个ThreadLocal对象threadXxx,用来保

存线程间需要隔离处理的对象xxx。 

2、在ThreadDemo类中,创建一个获取要隔离访问的数据的方法getXxx(),在方法中调用

ThreadLocal的get()方法,并强制转换为要应用的类型,然后断该对象是否为null,若需要隔离处理的对象xxx为null时候,应该new()一个隔离访问类型的对象,再通过ThreadLocal对象的set()方法将该对象放入。 

3、在ThreadDemo类的run()方法中,通过getXxx()方法获取要操作的数据,这样可以保

证每个线程对应一个数据对象,在任何时刻都操作的是这个对象。

举例:在Hibernate中

 public static final ThreadLocal session = new ThreadLocal();     public static Session getCurrentSession() {         Session s = (Session)session.get();         if(s == null){             s = sessionFactory.openSession();             session.set(s);         }         return s;     }






1 0