ThreadLocal的作用

先看一下官方描述:

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. {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).

ThreadLocal类提供线程局部变量。这些变量与普通的变量不同,因为每个访问一个变量的线程(通过其get或set方法)都有自己的、独立初始化的变量副本。ThreadLocal实例通常是类中希望将状态与线程(例如,用户ID或事务ID)关联的私有静态字段。

 

简单的讲就是第一句话:ThreadLocal类提供线程局部变量。

 

一般的局部变量的生命周期和作用域是跟方法绑定的,成员变量的是一个类实例,而ThreadLocal提供的变量生命周期是和作用域是当前的线程,每个线程之间时无法交叉访问的。

 

简单看一下ThreadLocal如何实现线程级别的局部变量。

Thread类中有一个threadLocals变量,threadLocals的类型是ThreadLocal的内部类ThreadLocalMap,

/* ThreadLocal values pertaining to this thread. This map is maintained
 * by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;

每次调用ThreadLocal的get和set方法时都会判断当前线程的threadaLocals是否为null,如果为null就会赋值一个新的ThreadLocalMap实例。所以每个线程实例的threadLocal对应的实例都是不同的。

调用ThreadLocal的set方法实际上是把值放到了当前线程的threadLocals中

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

可以看到,map的键值是ThreadLocal实例。

 

所以实现关键点就在于每个Thread实例都持有不同的ThreadLocalMap对象。

 

 

 

使用场景:变量为线程独享并且变量会在线程中多个实例方法中使用,可以避免函数传参,代码臃肿。

  1. PageHelper 的PageInfo
  2. Hibernate 的 ThreadLocal模式 Session
  3. Dubbo的RpcConetxt
  4. 日志的MDC
  5. spring的声明式事务
  6. spring的RequestContextHolder

 

贴个官方demo: 为线程生成唯一id

public class ThreadId {
      // Atomic integer containing the next thread ID to be assigned
      private static final AtomicInteger nextId = new AtomicInteger(0);
 
      // Thread local variable containing each thread's ID
      private static final ThreadLocal<Integer> threadId =
          new ThreadLocal<Integer>() {
              @Override protected Integer initialValue() {
                  return nextId.getAndIncrement();
          }
      };
 
      // Returns the current thread's unique ID, assigning it if necessary
      public static int get() {
          return threadId.get();
      }
  }

 

总结:

1.ThreadLocal是用来给线程创建局部变量的

2.ThreadLocal不是用来解决线程安全的,跟线程安全没有关系。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值