9.19. 什么是线程局部变量
当使用 ThreadLocal 维护变量时,ThreadLocal 为每个使用该变量的线程提供独立的变量副本,每个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本,是线程隔离的。线程隔离的秘密在于 ThreadLocalMap 类(ThreadLocal 的静态内部类)。
线程局部变量是指每个线程具有自己独立的变量副本,不同线程之间的同名变量互不干扰,可以实现线程内部的数据共享而不影响其他线程。线程局部变量可以通过特殊的语法和函数来定义和访问,常见的实现方式是使用 __thread 修饰符来声明。线程局部变量主要用于多线程编程中的共享数据管理和线程安全问题的解决。
线程局部变量是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享。Java 提供 ThreadLocal 类来支持线程局部变量,是一种实现线程安全的方式。但是在管理环境下(如 web 服务器)使用线程局部变量的时候要特别小心,在这种情况下,工作线程的生命周期比任何应用变量的生命周期都要长。任何线程局部变量一旦在工作完成后没有释放,Java 应用就存在内存泄露的风险。
ThreadLocal 的方法:void set(T value)、T get()以及T initialValue()。
ThreadLocal 是如何为每个线程创建变量的副本的:
首先,在每个线程 Thread 内部有一个 ThreadLocal.ThreadLocalMap 类型的成员变量 threadLocals,这个 threadLocals 就是用来存储实际的变量副本的,键值为当前ThreadLocal 变量,value 为变量副本(即T类型的变量)。初始时,在 Thread 里面,threadLocals 为空,当通过 ThreadLocal 变量调用 get() 方法或者 set() 方法,就会对Thread 类中的 threadLocals 进行初始化,并且以当前 ThreadLocal 变量为键值,以 ThreadLocal 要保存的副本变量为 value,存到 threadLocals。然后在当前线程里面,如果要使用副本变量,就可以通过 get 方法在 threadLocals 里面查找。
总结:
a、实际的通过ThreadLocal创建的副本是存储在每个线程自己的threadLocals中的
b、为何threadLocals的类型ThreadLocalMap的键值为ThreadLocal对象,因为每个线程中可有多个threadLocal变量,就像上面代码中的longLocal和stringLocal;
c、在进行get之前,必须先set,否则会报空指针异常;如果想在get之前不需要调用set就能正常访问的话,必须重写initialValue()方法
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论