聊聊ThreadLocal那些事

前言

这篇文章聊聊 ThreadLocal,我们经常会在一些开源中间件的源码中见到它的身影,比较常见的用途是保存上下文信息,还有就是保证了线程安全。

实际上,ThreadLocal 为每个线程提供一个单独的变量,确是一种保证线程安全的手段,ThreadLocal 创建的变量只能被当前线程访问,其他线程不得干涉。

ThreadLocal API

使用 ThreadLocal 其实非常简单,直接看下面的示例:


public class ThreadLocalSimpleDateFormat {
   
    private static final ThreadLocal<SimpleDateFormat> formatter = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMss HHmm"));

    public String formatDate(Date date) {
   
        return formatter.get().format(date);
    }
}    
  • 使用 withIntial() 静态方法 初始化变量
  • 调用 get() 方法获取当前线程的对象值

我们都知道 SimpleDateFormat 不是线程安全,所以上面使用 ThreadLocal 的方式来保证线程安全,保证每个线程都有特定的 SimpleDateFormat。

当然不只这两个方法,还有常见的 set()、initialValue()方法,使用起来都比较简单。

什么时候使用TheadLocal

有时候我们会遇到将某个变量和线程进行绑定起来的场景,一种方法是定义一个Map,其中key是线程ID,value是对象,这样每个线程都有属于自己的对象,同一个线程只能对应一个对象。

比如,定义一个计数器,每个线程需要有一个属于自己的计数器,保证线程安全。


public class Counter {
   
    private AtomicLong counter = new AtomicLong();

    private static Map<Long, Counter> counterMap = new ConcurrentHashMap<>();

    public static Counter getCounter() {
   
        long id = Thread.currentThread().getId();
        counterMap.putIfAbsent(id, new Counter());
        return counterMap.get(id);
    }

    public long incrementAndGet() {
   
        return counter.incrementAndGet();
    }
}

而 Java 提供了更简单的方法,也就是 ThreadLocal 工具类,使用 ThreadLocal 类可以直接给每个线程提供单独的计数器


public class ThreadLocal_Counter {
   
    private ThreadLocal<AtomicLong> threadLocal = new 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值