大发时时彩_时时彩开户_大发时时彩开户

真实项目中 ThreadLocal 的妙用

时间:2019-12-02 13:12:22 出处:大发时时彩_时时彩开户_大发时时彩开户

一、你这个 是 ThreadLocal

ThreadLocal 提供了应用线程的局部变量,每个应用线程都还还可不还可以通过 set() 和 get() 来对你这个 局部变量进行操作,但还会和一点应用线程的局部变量冲突,实现了应用线程间的据隔离。

简单讲:有兩个多获取用户的请求应用线程 A,愿因分析向 ThreadLocal 填充变量 AValue(非要被应用线程 A 操作),该变量对一点获取用户的请求应用线程 B、C...是隔离的.

最简单的使用法律最好的办法:

累似 一次 HTTP 请求应用线程中,利用 ThreadLocal 存储 Cookie 对象,进行情形管理。set Cookie:

private ThreadLocal httpThreadLocal = new ThreadLocal();

httpThreadLocal.set(“Cookie: sid=13420771402233”)

上端存储格式是 String ,实际场景存储的是具体的对象。在这次 HTTP 请求过程中,任何然后都还还可不还可以获取 Cookie 。获取法律最好的办法很简单 get Cookie:

String cookieValue = (String) httpThreadLocal.get();

Thread 与 ThreadLocal 对象引用关系图

二、你熟悉的场景

2.1 数据库连接池

比如一次请求应用线程进来,业务 Dao 还可不还可以更新 user 表和 user-detail 表。愿因分析是 new 出有兩个多数据库 Connection ,分别不同的 Connection 操作 user 表和 user-detail 表,就无法保证事务。非要 数据库连接池是怎么才能 才能 保证的?

答案是:利用 ThreadLocal 存储唯一 Connection 对象。每次请求应用线程,pool.getConnection 获取连接的然后还会另有兩个多操作:

  • 会从 ThreadLocal 获取 Connection 对象。愿因分析有,则保证了上端多个数据库操作共用同有兩个多 Connection ,从而保证了事务。
  • 愿因分析非要 ,往 ThreadLocal 新增Connection 对象,并返回到应用线程
错误的做法
public class XXXService {

    private Connection conn;
}

愿因分析 conn 是应用线程不安全的。另有兩个多会愿因多个请求公用有兩个多连接。请求量很大的情形下,延迟各种。你懂。

一点,使用 ThreadLocal 保证每个请求应用线程的 Connection 是唯一的。即每个应用线程有买车人的连接。

继续讲到 Spring 框架,在事务然后然后结束时,会给当前应用线程有兩个多Jdbc Connection,在整个事务过程,全是使用该应用线程绑定的connection来执行数据库操作,实现了事务的隔离性。Spring框架上端可是用的ThreadLocal来实现你这个 隔离

比如你访问百度、我访问百度,会有不同 Cookie 。一点你非要访问我的 Cookie,我可是能。顾名思义,使用 ThreadLocal 保证每个 HTTP 请求应用线程的 Cookie 是唯一的。

Cookie 另有兩个多才能做 Session 等情形管理。

三、实战场景

总结一下可是:ThreadLocal 还还可不还可以让同有兩个多应用线程中上下文之间数据共享

在上端章节 二、你熟悉的场景 真是介绍了可是 现有场景。非要 我这边具体的实战场景是你这个 ?

简单的例子:

适用满足你这个 个多多条件的场景:1.每个应用线程独有的一点信息,2.你这个 信息又会在多个法律最好的办法或类中用到。

  1. 有兩个多请求应用线程,上端有有兩个多异步小应用线程,各有有兩个多法律最好的办法。分别处里 A 或 B 业务
  2. 某种法律最好的办法是传递不可变的入参
  3. 另某种可是 ThreadLocal,放入 ThreadLocal 的入参,会被各个法律最好的办法共享。一点多个请求应用线程互不影响
僵化 的例子:

一次发货操作:会根据入参,进行组件化、流程编排话。非要 入参会被各个地方用到,一点一点流程组件是异步的(累似 new thread 操作的)。这然后还还可不还可以定有兩个多 XXContext 上下文:

public class XXContext {
    
    private static ThreadLocal<Map<Class<?>, Object>> context = new InheritableThreadLocal<>();
    
    /**
     * 把参数设置到上下文的Map中
     */
    public static void put(Object obj) {
        Map<Class<?>, Object> map = context.get();
        if (map == null) {
            map = new HashMap<>();
            context.set(map);
        }
        if (obj instanceof Enum) {
            map.put(obj.getClass().getSuperclass(), obj);
        } else {
            map.put(obj.getClass(), obj);
        }
    }
    
    /**
     * 从上下文中,根据类名取出参数
     */
    @SuppressWarnings("unchecked")
    public static <T> T get(Class<T> c) {
        Map<Class<?>, Object> map = context.get();
        if (map == null) {
            return null;
        }
        return (T) map.get(c);
    }
    
    /**
     * 清空ThreadLocal的数据
     */
    public static void clean() {
        context.remove();
    }
}

代码解析:

  • 全是 static 操作,累似 DateUtil 玩法
  • 记得每次请求应用线程后清理。还还可不还可以 AOP 去清理,加个注解就行。愿因分析同有兩个多请求应用线程愿因分析被业务方公用。

(完)

热门

热门标签