线程变量Threadlocal的使用

ThreadLocal,线程本地变量,也有些地方叫做线程本地存储。ThreadLocal为变量在每个线程中都创建了一个副本,每个线程可以访问自己内部的副本变量。

ThreadLocal类提供了以下四个方法:

public T get() { }  

public void set(T value) { }  

public void remove() { }  

protected T initialValue() { } 

  get()方法是用来获取ThreadLocal在当前线程中保存的变量副本,set()用来设置当前线程中变量的副本,remove()用来移除当前线程中变量的副本,initialValue()是一个protected方法,一般是用来在使用时进行重写的,它是一个延迟加载方法,

在每个线程Thread内部有一个ThreadLocal.ThreadLocalMap类型的成员变量threadLocals,这个threadLocals就是用来存储实际的变量副本的,键值为当前ThreadLocal变量,value为变量副本(即T类型的变量)。初始时,在Thread里面,threadLocals为空,当通过ThreadLocal变量调用get()方法或者set()方法,就会对Thread类中的threadLocals进行初始化,并且以当前ThreadLocal变量为键值,以ThreadLocal要保存的副本变量为value,存到threadLocals。在进行get之前,必须先set,否则会报空指针异常;如果想在get之前不需要调用set就能正常访问的话,必须重写initialValue()方法。最常见的ThreadLocal使用场景为 用来解决 数据库连接、Session管理等。

private static ThreadLocal<Connection> connectionHoldernew ThreadLocal<Connection>() {

public Connection initialValue() {

return DriverManager.getConnection(DB_URL);

} };

public static Connection getConnection() {

return connectionHolder.get();

}

下面例二:

public static void setHolder(FutureHolder holder) throws IllegalStateException { 

FutureHolder old = futureHolder.get(); 

if(old != null) { throw new IllegalStateException("cannot repeat init"); } futureHolder.set(holder); }

使用的时候直接调用类名.方法名返回一个对象然后直接操作,保存的时候调用类中的方法存贮在ThreadLocal中。

下面例三:

public abstract class WebSocketContextHolder {

    private static final ThreadLocal<WebSocketRequestAttributes> requestAttributesHolder =
            new NamedThreadLocal<WebSocketRequestAttributes>("WebSocket Request attributes");

    /**
     * 获取当前的 WebSocketRequestAttributes,线程局部存储中如果没有, 抛出异常
     * @return
     * @throws IllegalStateException
     */
    public static WebSocketRequestAttributes currentRequestAttributes() throws IllegalStateException {
        WebSocketRequestAttributes attributes = getRequestAttributes();
        if(attributes == null) {
            throw new IllegalStateException("no websocket attribute");
        }
        return attributes;
    }

    /**
     * 获取当前的 WebSocketRequestAttributes,线程局部存储中如果没有, 返回 null
     * @return WebSocketRequestAttributes
     */
    public static WebSocketRequestAttributes getRequestAttributes() {
        return requestAttributesHolder.get();
    }

    /**
     * 设置 WebSocketRequestAttributes, 放到线程局部存储中,如果已经有,抛出异常
     * @param attributes
     * @throws IllegalStateException
     */
    public static void setRequestAttributes(WebSocketRequestAttributes attributes) throws IllegalStateException {
        WebSocketRequestAttributes old  = requestAttributesHolder.get();
        if(old != null)
            throw new IllegalStateException("cannot repeat init");
        requestAttributesHolder.set(attributes);
    }

    /**
     * 清理线程局部存储中数据
     */
    public static void clearRequestAttributes() {
      requestAttributesHolder.remove();
    }

    /**
     * 帮助清理 WebSocketRequestAttributes
     * @param attributes
     */
    public static void clean(WebSocketRequestAttributes attributes) {
        attributes.clearAll();
    }

}
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值