ThreadLocal 为什么存在?

变量值的共享可以使用public static 的形式,但每个线程都可以进行访问。如何实现每一个线程内的变量共享?
使用 ThreadLocal

类ThreadLocal主要解决的就是每个线程绑定自己的值,可以将ThreadLocal类比喻成全局存放数据的盒子,盒子中可以存储每个线程的私有数据。

设置值与取值

  1. // 赋值
  2. public void set(T value);
  3. // 取值,无值时返回null
  4. public T get();

验证线程变量的隔离性

  1. package com.hanliukui.example.threadlocaltest;
  2. /**
  3. * @Author hanliukui
  4. * @Date 2022/4/4 15:22
  5. * @Description xxx
  6. */
  7. public class Main {
  8. static ThreadLocal<String> local = new ThreadLocal();
  9. public static void main(String[] args) {
  10. Thread threadA = new Thread(new Runnable() {
  11. @Override
  12. public void run() {
  13. for (int i = 0; i < 10; i++) {
  14. local.set("ThreadA"+i);
  15. System.out.println("ThreadA获取值:"+local.get());
  16. }
  17. }
  18. });
  19. Thread threadB = new Thread(new Runnable() {
  20. @Override
  21. public void run() {
  22. for (int i = 0; i < 10; i++) {
  23. local.set("ThreadB"+i);
  24. System.out.println("ThreadB获取值:"+local.get());
  25. }
  26. }
  27. });
  28. threadA.start();
  29. threadB.start();
  30. try {
  31. Thread.sleep(1000);
  32. } catch (InterruptedException e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. }

ThreadB获取值:ThreadB0 ThreadA获取值:ThreadA0 ThreadB获取值:ThreadB1 ThreadA获取值:ThreadA1 ThreadB获取值:ThreadB2 ThreadB获取值:ThreadB3 ThreadB获取值:ThreadB4 ThreadB获取值:ThreadB5 ThreadA获取值:ThreadA2 ThreadB获取值:ThreadB6 ThreadA获取值:ThreadA3 ThreadB获取值:ThreadB7 ThreadB获取值:ThreadB8 ThreadA获取值:ThreadA4 ThreadB获取值:ThreadB9 ThreadA获取值:ThreadA5 ThreadA获取值:ThreadA6 ThreadA获取值:ThreadA7 ThreadA获取值:ThreadA8 ThreadA获取值:ThreadA9

解决get()返回null的问题

创建子类重写 ThreadLocal 的 initialValue() 方法;

  1. protected T initialValue() {
  2. return null;
  3. }