zoukankan      html  css  js  c++  java
  • ThreadLocal

    一、两大使用场景——ThreadLocal的用途

    典型场景1:

      每个线程需要独享一个对象(通常是工具类,典型需要使用的类有SimpleDateFormat和Random)
    每个Thread内有自己的实例副本,不共享
      比喻:教材只有一本,一起做笔记有线程安全问题。复印后没问题

    SimpleDateFormat的进化之路:

      1、2个线程分别用自己的SimpleDateFormat,这没问题
      2、后来延伸出10个
      3、但是当需求变成了1000个,那么必然要使用线程池
      4、所有的线程都共用一个静态的SimpleDateFormat对象,但是出现了线程安全问题,通过加锁解决了问题,但是加锁会影响任务的执行效率
      5、利用ThreadLocal,给每个线程分配自己的dateFormat对象,保证了线程安全

    典型场景2:

      每个线程内需要保存全局变量(例如在拦截器中获取用户信息),可以让不同方法直接使用,避免参数传递的麻烦
      用ThreadLocal保存一些业务内容(用户权限信息、从用户系统获取到用户名、user ID等)
      这些信息在同一个线程内相同,但是不同的线程使用的业务内容是不相同的
      在线程生命周期内,都通过这个静态ThreadLocal实例的get()方法取得自己set过的那个对象,避免了将这个对象(例如user对象)作为参数传递的麻烦
      强调的是同一个请求内(同一个线程内)不同方法间的共享
      不需重写initialValue()方法,但是必须手动调用set()方法
    ThreadLocal的两个作用
      1、让某个需要用到的对象在线程间隔离(每个线程都有自己的独立对象)
      2、在任何方法中都可以轻松获取到该对象
    根据共享对象的生成时机不同,选择initialValue或set来保存对象
      场景一:initialValue
        在ThreadLocal第一次get的时候把对象给初始化出来,对象的初始化时机可以由我们控制
      场景二:set
        如果需要保存到ThreadLocal里的对象的生成时机不由我们随意控制,例如拦截器生成的用户信息
        用ThreadLocal.set直接放到我们的ThreadLocal中去,一遍后续使用

    二、使用ThreadLocal带来的好处

    达到线程安全
    不需要加锁,提高执行效率
    更高效地利用内存、节省开销(相比于每个任务都新建一个SimpleDateFormat,显然用ThreadLocal可以节省内存和开销)
    免去传参的繁琐(不需要每次都传同样的参数,ThreadLocal使得代码耦合度更低,更优雅)

    三、主要方法介绍

    T initialValue():初始化
      1、该方法会返回当前线程对应的"初始值",这是一个延迟加载的方法,只有在调用get的时候,才会触发
      2、当线程第一次使用get方法访问变量时,将调用此方法
      3、每个线程最多调用一次此方法,但如果已经调用了remove()后,再调用get(),则可以再次调用此方法
      4、如果不重写本方法,这个方法会返回null。一般使用匿名内部类的方法来重写initialValue()方法
    void set(T t):为这个线程设置一个新值
    T get():得到这个线程对应的value。如果是首次调用get(),则会调用initialValue来得到这个值
    void remove():删除对应这个线程的值

    四、注意点

    1、内存泄漏
    什么是内存泄漏?
      某个对象不再有用,但是占用的内存却不能被回收
    如何避免内存泄漏?
      调用remove方法,就会删除对应的Entry对象,可以避免内存泄漏,所以使用完ThreadLocal之后,应该调用remove方法。
    2、空指针异常
      空指针异常并不是由ThreadLocal导致,而是由装箱、拆箱导致的
    3、共享对象
    4、如果可以不使用ThreadLocal就解决问题,那么不要强行使用
    5、优先使用框架的支持,而不是自己创造

  • 相关阅读:
    SQLAlchemy技术文档(中文版)(全)
    Python 学习 第17篇:sqlalchemy 读写SQL Server数据库
    环境:Pycharm2019.1 + Win10 + Python3.7.3
    PyInstaller打包python脚本的一些心得
    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了)
    简单使用xlwt
    python xlwt写入excel操作
    Python中xlrd模块解析
    python使用pip离线安装库
    pip的基本使用和离线安装Python第三方库
  • 原文地址:https://www.cnblogs.com/michealyang/p/14142242.html
Copyright © 2011-2022 走看看