ThreadLocal的用法理解

  • 其实很简单,就是创建一个对象,然后每个线程去访问时,访问的是这个对象的副本。即该对象会为每个线程拷贝出一个副本。
  • 其实效果和local variable是一个效果。即在线程内初始化一个本地变量。
ThreadLocal<String> threadLocalOld = new ThreadLocal<String>(){
  @Override
  protected String initialValue() {
    return new String("dsadsa");
  }
};
Thread thread = new Thread(()->{
  String s = threadLocalOld.get();//每个线程调度get函数获取本线程的副本。
  // do sth
  threadLocalOld.set("dsad");// set函数set的值,只会设置本线程的值,不会对其他线程有任何影响。
});
Thread thread1 = new Thread(()->{
  String s = new String("dsadsa");//ThreadLocal效果定义local variable类似。
  // do sth
});

但ThreadLocal要比local variable优点:
1. 当我们需要给线程传递数据时,
如果这个数据是线程安全的(不可变的)或线程处理中是只读操作,那线程中直接使用即可。
如果这个数据是非线程安全的,则使用ThreadLocal是一个好的选择。相比在线程中定义一个这个数据的副本要好。因为ThreadLocal有更大的scope。
2. 线程内全局变量的效果。
我们在线程内可以通过set和get得到,即set的值可以在线程内anywhere通过get得到 。所以如果线程函数内有多层嵌套调用,则无需传递此值。其实相当于线程内的全局变量。

ThreadLocal的误用:

public static void main(String[] args){
  TT tt = new TT("a", 1);
  ThreadLocal<TT> ttThreadLocal = ThreadLocal.withInitial(()->tt);
  Thread t1 = new Thread(()->{
    ttThreadLocal.get().setS("b");
  });
  t1.start();
  try {
    t1.join();
    System.out.println(JSON.toJSONString(tt));
  } catch (Exception e) {
    e.printStackTrace();
  }
}

此时的输出是{“i”:1,”s”:”b”}。
即initialValue的误用。即ThreadLocal在线程调用的时候就会去调用initiaValue来得到本线程的副本,而如果用户自己写的initialValue函数并不是new一个对象,而是直接返回全局变量,则这里就会出错。即t1线程修改的值在主线程中可以看到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值