Java ThreadLocal用法详解(附带实例)
ThreadLocal 很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal 并不是一个 Thread,而是 Thread 的局部变量。
当使用 ThreadLocal 维护变量时,ThreadLocal 为每个使用该变量的线程提供独立的变量副本,因此每一个线程都可以独立地改变自己的副本,而不会影响其他线程对应的副本。
ThreadLocal 是由 JDK 包提供的线程本地变量,如果你创建了一个 ThreadLocal 变量,那么访问这个变量的每个线程都会有这个变量的一个本地副本。当多个线程操作这个变量时,实际操作的是自己本地内存里面的变量,从而避免了线程安全问题。
Java 提供了 3 个用于操作 ThreadLocal 变量的方法,即 set() 方法、get() 方法和 remove() 方法:
【实例】用户线程等待守护线程。创建一个全局的静态 ThreadLocal 变量,存储 String 类型变量;创建两个线程,分别为 threadOne 和 threadTwo:
开启线程 threadOne 和 threadTwo,执行程序,并观察输出结果。代码如下:
当使用 ThreadLocal 维护变量时,ThreadLocal 为每个使用该变量的线程提供独立的变量副本,因此每一个线程都可以独立地改变自己的副本,而不会影响其他线程对应的副本。
ThreadLocal 是由 JDK 包提供的线程本地变量,如果你创建了一个 ThreadLocal 变量,那么访问这个变量的每个线程都会有这个变量的一个本地副本。当多个线程操作这个变量时,实际操作的是自己本地内存里面的变量,从而避免了线程安全问题。
Java 提供了 3 个用于操作 ThreadLocal 变量的方法,即 set() 方法、get() 方法和 remove() 方法:
- set() 方法负责设置 ThreadLocal 变量,设置成功后,该变量只能够被当前线程访问,其他线程不可直接访问、操作该变量。set() 方法可以设置任何类型的值,无论是 String 类型,Integer 类型,Object 类型等,原因在于 set() 方法的 JDK 源码实现是基于泛型的实现;
- get() 方法负责获取 ThreadLocal 变量的值,get() 方法没有任何入参,直接调用即可获取;
- remove() 方法负责清除 ThreadLocal 变量,清除成功后,该变量中没有值。remove() 方法同 get() 方法一样,是没有任何入参的,因为 ThreadLocal 变量中只能存储一个值,那么 remove() 方法会直接清除这个变量值。
【实例】用户线程等待守护线程。创建一个全局的静态 ThreadLocal 变量,存储 String 类型变量;创建两个线程,分别为 threadOne 和 threadTwo:
- threadOne 线程调用 set() 方法进行设置,设置完成后休眠 5000 毫秒,苏醒后调用 get() 方法进行输出;
- threadTwo 线程调用 set() 方法进行设置,设置完成后直接调用 get() 方法进行输出,输出完成后调用 remove() 方法,并输出 remove() 方法被调用完毕的语句;
开启线程 threadOne 和 threadTwo,执行程序,并观察输出结果。代码如下:
public class Demo { static ThreadLocal<String> local = new ThreadLocal<>(); public static void main(String[] args){ Thread threadOne = new Thread(new Runnable() { @Override public void run() { local.set("threadOne's local value"); try { Thread.sleep(5000); // 休眠 5000 毫秒,确保 threadTwo 线程执行 remove()方法 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(local.get()); } }); Thread threadTwo = new Thread(new Runnable() { @Override public void run() { local.set("threadTwo's local value"); System.out.println(local.get()); local.remove(); System.out.println("local 变量已经执行 remove()方法。"); } }); threadOne.start(); threadTwo.start(); } }运行结果为:
threadTwo's local value
local变量已经执行remove()方法。
threadOne's local value