Java ThreadLocal源码分析

Java ThreadLocal源码分析


1.首先举一个栗子

public static class MyExample {

    private static ThreadLocal<Integer> age = ThreadLocal.withInitial(() -> 0);
    private static ThreadLocal<String> name = new ThreadLocal<String>() {
      public String initialValue() {
        return "default";
      }
    };

    public static void main(String[] args) {
      new Thread(() -> {
        age.set(30);
        name.set("zhang tongxue");
        System.out.println(Thread.currentThread() + " " + age.get());
        System.out.println(Thread.currentThread() + " " + name.get());
      }).start();
      new Thread(() -> {
        try {
          Thread.sleep(200);
        } catch (InterruptedException ignore) {
        }
        System.out.println(Thread.currentThread() + " " + age.get());
        System.out.println(Thread.currentThread() + " " + name.get());
      }).start();
    }
  }

执行结果:

Thread[Thread-0,5,main] 30
Thread[Thread-0,5,main] zhang tongxue
Thread[Thread-1,5,main] 0
Thread[Thread-1,5,main] default

2.分析

类结构

这里写图片描述

实际存储结构

这里写图片描述

源码

set方法

    public void set(T value) {
        Thread t = Thread.currentThread();//获取当前线程
        ThreadLocalMap map = getMap(t);//t.threadLocals 获取线程中的Map
        if (map != null)
            map.set(this, value);//Map常规散列表
        else
            createMap(t, value);
    }

get方法

    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);//散列表,先求hashcode
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }

总结

  • 每个线程私有一份拷贝的变量,这里实现非常巧妙,也容易会被面试官问你如何设计Threadlocal(假如你不知道实现的话)
  • ThreadLocal只是对需要存储的对象的管理,而存储实际是由当前Thread负责。
  • 使用ThreadLocal可以使对象达到线程隔离的目的。同一个ThreadLocal操作不同的Thread,实质是各个Thread对自己的变量操作。
使用场景
  • 为什么要使用ThreadLocal,个人感觉有两个原因:
    • 1.是与其它线程的隔离
    • 2.是可以在一个线程的生命周期中使用同一个对象

在一些业务处理中,组件之间处理同一个业务,需要处理很多上下文信息(输入,调用参数,中间结果),往往通过threadlocal 方式比较优雅。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值