深入理解ThreadLocal

本文详细介绍了ThreadLocal在Struts2中的使用原理及其实现机制,包括其如何为每个线程创建独立的变量副本,减少多线程环境下变量共享的复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Struts2的笔记中,在学习关于调用ServletAPI的过程中,我们接触到关于如何获取ActionContext对象,它是通过ThreadLocal设定一个为线程所独享的对象。关于ThreadLocal,我有所疑惑,所以单独列出来探索一下。

ThreadLocal的介绍


ThreadLocal在java.lang包下,译为线程局部变量,它并不是为了解决多线程共享变量而存在的,而是为每个线程创建一个独立的变量副本

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its {@code get} or {@code set} method) has its own, independently initialized copy of the variable. {@code ThreadLocal} instances are typically private static fields in classes that wish to associate state with a thread (e.g.,a user ID or Transaction ID)

大致意思是:该类提供线程局部变量,这些变量不同于通常的副本,它们会在每个线程独立初始化一个属于自己的拷贝,这就保证了即使在多线程的环境下(通过get和set方法),每个线程里的变量依然独立于其他变量。线程局部变量通常是关联线程的静态私有变量,用以关联线程以及线程的上下文。其生命周期和线程生命周期相关。
ThreadLocal显著地降低了一个线程内,多个函数、或者组件访问某个公共变量的复杂度。
ThreadLocal常常应用于按线程多实例的场景,典型应用就是Struts2中的ActionContext,以下是ActionContext源码中的静态属性。

static ThreadLocal<ActionContext> actionContext = new ThreadLocal();

ThreadLocal的操作


ThreadLocal常用的4个方法,分别是:

initialValue()

initialValue():该方法返回局部变量的初始值,这个方法是protected方法,这意味着它能够被子类重写,事实上,它就是用来被子类重写的。这是一个延迟加载方法,只有在线程第一次调用get或者set方法时才执行,并且只执行一次,该方法的缺省返回值为null。

protected T initialValue() {
        return null;
    }
get()

该方法返回当前线程中的线程局部变量

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

如果当前线程中没有局部变量值,那么就会返回初始值。

set()

用以设定当前线程的局部变量。

public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
remove()
public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
     }

用以删除当前线程中的局部变量。

//TODO

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值