ThreadLocal

来源:互联网 发布:js数组内数组拆分 编辑:程序博客网 时间:2024/06/05 10:16

ThreadLocal
源码讲解
通过Thread.currentThread()获取当前线程
通过ThreadLocal.ThreadLocalMap inheritableThreadLocals =null;绑定该线程所占用的资源。(threadLocal只是个key)
概述:ThreadLocal就是为thread维护中的一个ThreadLocalMap的工具类而已,具体资源完全和当前线程绑定
以下三个方法的实现代码辅助理解

   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)                return (T)e.value;        }        return setInitialValue();    }
public void remove() {         ThreadLocalMap m = getMap(Thread.currentThread());         if (m != null)             m.remove(this);     }

理解
线程绑定,管理单一无状态资源,存储直到当前线程销毁
常见于连接(绑定线程不会造成冲突,随着线程的销毁而随之归还)管理
如hibernate的session

 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;    }

不解决并发访问的问题,在并发场景应用此类作为数据存储会存在问题
注:误用实例
比如说用当前类去做服务器端的用户信息存储的时候,并且有10个用户同时登陆当前系统,这个时候每一个操作人的操作过程服务器端通过threadlocal获取到的用户对象都有可能是这10个登录人中的其中一个,会引起数据混乱

误用代码实例

public class LoginUtils {    private static String                       key_prefix  = "***_***";    private static final ThreadLocal<LoginUser> threadLocal = new ThreadLocal<LoginUser>();    private static LoginUtils                   cacheUtil;    @Autowired    private TairService                         tairService;    @PostConstruct    public void init() {        cacheUtil = this;        cacheUtil.tairService = this.tairService;    }    public static void setUser(LoginUser user) {        threadLocal.set(user);        cacheUtil.tairService.put(buildKey(user), user);    }    public static LoginUser getUser() {        return threadLocal.get();    }    public static void removeUser() {        LoginUser user = threadLocal.get();        if (user == null) {            return ;        }        threadLocal.remove();        cacheUtil.tairService.delete(buildKey(user));    }    public static String buildKey(LoginUser user) {        StringBuffer key = new StringBuffer();        key.append(key_prefix);        key.append(user.getId());        return key.toString();    }}

ThreadLocal

0 0
原创粉丝点击