ThreadLocal

ThreadLocal

当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

线程隔离的秘密

线程隔离的秘密,就在于ThreadLocalMap这个类。ThreadLocalMap是ThreadLocal类的一个静态内部类,它实现了键值对的设置和获取(对比Map对象来理解),每个线程中都有一个独立的ThreadLocalMap副本,它所存储的值,只能被当前线程读取和修改。ThreadLocal类通过操作每一个线程特有的ThreadLocalMap副本,从而实现了变量访问在不同线程中的隔离。因为每个线程的变量都是自己特有的,完全不会有并发错误。还有一点就是,ThreadLocalMap存储的键值对中的键是this对象指向的ThreadLocal对象,而值就是你所设置的对象了。

set源码:

public void set(T value) {  
       Thread t = Thread.currentThread(); //获取当前线程 
       ThreadLocalMap map = getMap(t);    //获取每个线程独立的ThreadLocalMap副本
       if (map != null)  
           map.set(this, value);     //this:ThreadLocal对象
       else  
           createMap(t, value);  
   }  

get源码:

public T get() {  
    Thread t = Thread.currentThread();  //获取当前线程 
    ThreadLocalMap map = getMap(t);  //获取每个线程独立的ThreadLocalMap副本
    if (map != null) {  
        ThreadLocalMap.Entry e = map.getEntry(this);//通过当前ThreadLocal对象获取值  
        if (e != null)  
            return (T)e.value;  
    }  
    return setInitialValue();  
}  

setInitialValue源码:

private T setInitialValue() {  
       T value = initialValue();  //默认情况下,initialValue方法返回的是null,可以重写这个方法,赋予初始值
       Thread t = Thread.currentThread();  
       ThreadLocalMap map = getMap(t);  
       if (map != null)  
           map.set(this, value);  
       else  
           createMap(t, value);  
       return value;  
   }  

Thread同步机制的比较

概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

应用

spring 如何保证数据库事务在同一个连接下执行的

DataSourceTransactionManager 是spring的数据源事务管理器, 它会在你调用getConnection()的时候从数据库连接池中获取一个connection, 然后将其与ThreadLocal绑定, 事务完成后解除绑定。这样就保证了事务在同一连接下完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值