ThreadLocal模式的纵向隔离与横向隔离

本文深入解析了ThreadLocal模式的工作原理,包括其纵向隔离与横向隔离特性,并通过具体代码示例展示了ThreadLocal如何在多线程环境中实现数据隔离。

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

《struts2技术内幕》中说到了TheadLocal模式的纵向隔离与横向隔离问题,这里写细一些帮助记忆


图1


如上图每个thread中都有一个ThreadLocalMap变量,并且其中以各个ThreadLocal实例为key存着变量。

这样thread之间即为同一threadlocal类不同实例的纵向隔离。

一个thread内ThreadLocalMap根据不同ThreadLocal得到相应变量值即为横向隔离。


具体到后面的例子代码如下:

public class Counter {
	
// 新建一个静态的ThreadLocal变量,并通过get方法将其变为一个可访问的对象
    private static ThreadLocal<Integer> counterContext = new ThreadLocal<Integer>() {
	 protected synchronized Integer initialValue() {
	         return 10;
	 }
};
	
// 通过静态的get方法访问ThreadLocal中存储的值
public static Integer get() {
	return counterContext.get();
}
	
// 通过静态的set方法将变量值设置到ThreadLocal中
public static void set(Integer value) {
	counterContext.set(value);
}
	
// 封装业务逻辑,操作存储于ThreadLocal中的变量
public static Integer getNextCounter() {
    counterContext.set(counterContext.get() + 1);
    return counterContext.get();
}
    
}
虽然Count中counterContext是类变量,然而在执行getNextCounter()时,threadlocal的set方法已经获得当前线程对象,并且得到线程对象中的ThreadLocalMap,将自己与要保存的值存成了图1的结构。

public class ThreadLocal<T> {

// 这里省略了许多其他代码

// 将value的值保存于当前线程的本地变量中
public void set(T value) {
    // 获取当前线程
    Thread t = Thread.currentThread();
    // 调用getMap方法获得当前线程中的本地变量ThreadLocalMap
    ThreadLocalMap map = getMap(t);
    // 如果ThreadLocalMap已存在,直接使用
    if (map != null)
         // 以当前的ThreadLocal的实例作为key,存储于当前线程的
         // ThreadLocalMap中,如果当前线程中被定义了多个不同的ThreadLocal
         // 的实例,则它们会作为不同key进行存储而不会互相干扰
         map.set(this, value);
    else
         // ThreadLocalMap不存在,则为当前线程创建一个新的
         createMap(t, value);
}

 // 获取当前线程中以当前ThreadLocal实例为key的变量值
public T get() {
    // 获取当前线程
    Thread t = Thread.currentThread();
    // 获取当前线程中的ThreadLocalMap
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        // 获取当前线程中以当前ThreadLocal实例为key的变量值
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null)
            return (T)e.value;
    }
    // 当map不存在时,设置初始值
    return setInitialValue();
}

// 从当前线程中获取与之对应的ThreadLocalMap
ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
}

 // 创建当前线程中的ThreadLocalMap
void createMap(Thread t, T firstValue) {
    // 调用构造函数生成当前线程中的ThreadLocalMap
    t.threadLocals = new ThreadLocalMap(this, firstValue);
}

// ThreadLoaclMap的定义
static class ThreadLocalMap {
    // 这里省略了许多代码
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值