可爱静

记录生活、学习和工作

0%

ThreadLocal

摘要

ThreadLocal介绍

ThreadLocal是什么

  • ThreadLocal类用来提供线程内部的局部变量。这种变量在多线程环境下访问(通过get和set方法访问)时能保证各个线程的变量相对独立于其他线程内的变量。ThreadLocal实例通常来说都是private static类型的,用于关联线程和线程上下文。

    ThreadLocal的作用

  • 多线程访问同一个共享变量的时候容易出现并发问题,特别是多个线程对一个变量进行写入的时候,为了保证线程安全,一般使用者在访问共享变量的时候需要进行额外的同步措施才能保证线程安全性。ThreadLocal是除了加锁这种同步方式之外的一种保证一种规避多线程访问出现线程不安全的方法,当我们在创建一个变量后,如果每个线程对其进行访问的时候访问的都是线程自己的变量这样就不会存在线程不安全问题。

    ThreadLocal基本使用

    ThreadLocal的常见方法

    方法声明 方法
    ThreadLocal() 创建ThreadLocal对象
    public void set(T value) 设置当前线程绑定的局部变量
    public T get() 获取当前线程绑定的局部变量
    public void remove() 移除当前线程绑定的局部变量

    Show Code

  • 未注入ThreadLocal()
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class ThreadLocal01 {
    // 变量
    private String content;

    public String getContent() {
    return content;
    }

    public void setContent(String content) {
    this.content = content;
    }

    // 未引入ThreadLocal
    public static void main(String[] args) {
    ThreadLocal01 threadLocal01 = new ThreadLocal01();
    for (int i = 0; i < 5; i++) {
    new Thread(() -> {
    threadLocal01.setContent(Thread.currentThread().getName() + "的数据");
    System.out.println("-----------------------------------------");
    System.out.println(Thread.currentThread().getName() + "\t " + threadLocal01.getContent());
    }, String.valueOf(i)).start();
    }
    }
    }
    执行结果
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    -----------------------------------------
    -----------------------------------------
    4 4的数据
    -----------------------------------------
    3 4的数据
    -----------------------------------------
    0 4的数据
    -----------------------------------------
    1 4的数据
    2 4的数据

  • 引入ThreadLocal
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    public class ThreadLocal01 {
    // 变量
    private String content;

    public String getContent() {
    return content;
    }

    public void setContent(String content) {
    this.content = content;
    }

    // 引入ThreadLocal
    public static void main(String[] args) {
    ThreadLocal01 threadLocal01 = new ThreadLocal01();
    ThreadLocal<String> threadLocal = new ThreadLocal<>();
    for (int i = 0; i < 5; i++) {
    new Thread(() -> {
    threadLocal.set(Thread.currentThread().getName() + "的数据");
    System.out.println("-----------------------------------------");
    System.out.println(Thread.currentThread().getName() + "\t " + threadLocal.get());
    },String.valueOf(i)).start();
    }
    }
    }
    执行结果
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    -----------------------------------------
    0 0的数据
    -----------------------------------------
    4 4的数据
    -----------------------------------------
    3 3的数据
    -----------------------------------------
    2 2的数据
    -----------------------------------------
    1 1的数据
  • 通过 set 将变量绑定到当前线程中,然后 get 获取当前线程绑定的变量,也就是当前线程只能获取线程线程存储的对象。

    ThreadLocal与Synchronized的区别

  • 虽然ThreadLocal模式与Synchronized关键字都用于处理多线程并发访问变量的问题,不过两者处理问题的角度和思路不同。
Synchronized ThreadLocal
原理 同步机制采用 以空间换时间 的方式,只提供了一份变量,让不同的线程排队访问 ThreadLocal采用以空间换时间的概念,为每个线程都提供一份变量副本,从而实现同时访问而互不干扰
侧重点 多个线程之间访问资源的同步 多线程中让每个线程之间的数据相互隔离