ThreadLocal使用场景

场景一

每个线程需要一个独享的对象(通常是工具类,典型需要使用的类有SimpleDateFormat和Random)

  • 每个Thread内有自己的实例副本,不共享

场景二

每个线程内需要保存全局变量(例如在拦截器中获取用户信息),可以让不同方法直接使用,避免参数传递的麻烦

注意点

  • 空指针异常:在进行get之前,必须先set,否则报空指针异常?ThreadLocal不会报NPE,原因可能是拆装箱导致!
  • 共享对象:若每个线程中ThreadLocal.set()的值本来就是多线程共享的同一个对象,比如static对象,那么多个线程的ThreadLocal.get()取得的还是这个共享对象本身,还是会存在并发访问问题!
  • 适当运用:若可以不用ThreadLocal就可解决问题,就可不强行使用
  • 优先选择框架,而非自己创造,如Spring的RequestContextHolder

对象拷贝

深拷贝和浅拷贝区别

浅拷贝

  • 浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址, 所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝(例: assign())

    深拷贝

  • 深拷贝是将对象及值复制过来,两个对象修改其中任意的值另一个值 不会改变,这就是深拷贝(例:JSON.parse()和 JSON.stringify(),但是此方法无法复制函数类型)

  • 例如:a、使用clone方法; b、通过对对象序列化实现深拷贝(推荐使用)

    举例

  • 举个例子;文件的复制是深拷贝,创建快捷方式是浅拷贝。

  • 浅拷贝,只是对象级别的拷贝引用,而深拷贝则是逐层拷贝创建新的对象。
  • 构造函数、重载clone、序列化工具都可以做深拷贝,如图;
  • image.png
  • 通常使用的时候,结合自己的场景,是否使用了拷贝的值,会被原对象的改变受到影响。