Threadlocal

来源:互联网 发布:华师在线网络教育怎么 编辑:程序博客网 时间:2024/05/16 07:12

1.应用:

变量是同一个,但是每个线程都使用同一个初始值,也就是使用同一个变量的一个新的副本。

例如:DAO的数据库连接,我们知道DAO是单例的,那么他的属性Connection就不是一个线程安全的变量。而我们每个线程都需要使用他,并且各自使用各自的。这种情况,ThreadLocal就比较好的解决了这个问题;Spring的Singleton是线程安全的也是因为使用了ThreadLocal

public class ConnectionUtil {    private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();    private static Connection initConn = null;    static {        try {            initConn = DriverManager.getConnection("url, name and password");        } catch (SQLException e) {            e.printStackTrace();        }    }        public Connection getConn() {        Connection c = tl.get();        if(null == c) tl.set(initConn);        return tl.get();    }    }
原理:每个Thread对象内部都维护了一个ThreadLocalMap这样一个ThreadLocal的Map,可以存放若干个ThreadLocal。

当我们在调用get()方法的时候,先获取当前线程,然后获取到当前线程的ThreadLocalMap对象,如果非空,那么取出ThreadLocal的value,否则

进行初始化,初始化就是将initialValue的值set到ThreadLocal中。源码:

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

当我们调用set()方法的时候,很常规,就是将值设置进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);    }


应用场景:当很多线程需要多次使用同一个对象,并且需要该对象具有相同初始化值的时候最适合使用ThreadLocal。


原创粉丝点击