ThreadLocal使用场景详解(3种常见使用场景)

ThreadLocal使用场景详解(3种常见使用场景)-mikechen

之前ThreadLocal的作用谈到了ThreadLocal主要解决多线程并发时访问共享变量的问题。

ThreadLocal原理实现主要是通过数据隔离的方式来解决,ThreadLocal在每个线程都创建副本,每个线程可以访问自己的副本,线程之间相互不影响。

ThreadLocal使用场景详解(3种常见使用场景)-mikechen

今天我们重点谈谈ThreadLocal的使用场景,在通常的业务开发中ThreadLocal 有以下3种典型的使用场景。

如下图所示:

ThreadLocal使用场景详解(3种常见使用场景)-mikechen

1.解决线程安全问题

ThreadLocal 用作保存每个线程独享的对象,为每个线程都创建一个副本,这样每个线程都可以修改自己所拥有的副本, 而不会影响其他线程的副本,确保了线程安全。

举例说明,比如Java7中的SimpleDateFormat不是线程安全的,可以用ThreadLocal来解决这个问题。

示例如下:

public class DateUtil {
    private static ThreadLocal<SimpleDateFormat> format1 = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };

    public static String formatDate(Date date) {
        return format1.get().format(date);
    }
}

以上主要解决线程安全问题,对于需要进行线程隔离的变量,可以使用ThreadLocal存储,确保线程隔离。

 

2.代替参数的显式传递

当我们在写API接口的时候,通常Controller层会接受来自前端的入参,当这个接口功能比较复杂的时候,可能我们调用的Service层内部还调用了 很多其他的很多方法,通常情况下,我们会在每个调用的方法上加上需要传递的参数。

但是如果我们将参数存入ThreadLocal中,那么就不用显式的传递参数了,而是只需要ThreadLocal中获取即可。

这是因为使用参数传递造成代码的耦合度高,使用静态全局变量在多线程环境下不安全,当该对象用ThreadLocal包装过后,就可以保证在该线程中独此一份,同时和其他线程隔离。

例如在Spring的@Transaction事务声明的注解中就使用ThreadLocal保存了当前的Connection对象,避免在本次调用的不同方法中使用不同的Connection对象。

 

3.全局存储用户信息

可以尝试使用ThreadLocal替代Session的使用,当用户要访问需要授权的接口的时候,可以现在拦截器中将用户的Token存入ThreadLocal中,之后在本次访问中任何需要用户用户信息的都可以直接冲ThreadLocal中拿取数据。

一个简单的用ThreadLocal来存储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;
    }

 

 

作者简介

陈睿|mikechen,10年+大厂架构经验,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注作者「mikechen」公众号,获取更多技术干货!

后台回复架构,即可获取《阿里架构师进阶专题全部合集》,后台回复面试即可获取《史上最全阿里Java面试题总结

评论交流
    说说你的看法