引言
ThreadLocal的官方API解释为:
上述英文啥意思呢?翻译过来:“该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。”
ThreadLocal 的作用
ThreadLocal是解决线程安全问题一个很好的思路,它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。
ThreadLocal 的使用
threadlocal使用方法也很简单
static final ThreadLocal<T> threadLocal = new ThreadLocal<T>();
/** 设置变量 */
threadLocal.set(T)
/** 获取变量 */
threadLocal.get()
/** 移除变量 */
threadLocal.remove()
下面写一个简单的demo来搞懂ThreadLocal
/**
* ThreadLocal 简单demo
*
* @author ritian
* @since 2020/5/21 12:23
**/
public class ThreadLocalDemo {
/**
* 初始化
*/
private static ThreadLocal<GirlFriend> gfThreadLocal = ThreadLocal.withInitial(() -> new GirlFriend("xx老湿", "D"));
public static void main(String[] args) throws Exception{
System.out.println("有一天,小明和小李同时来到好朋友老王家,同时看到了" +gfThreadLocal.get());
new Thread(new Programmer("程序员小明", "A")).start();
new Thread(new Programmer("程序员小李", "G")).start();
Thread.sleep(3000);
System.out.println("3秒后,老王回过神,看着"+gfThreadLocal.get().toString()+",还好还好,it's my style");
}
/**
* 程序员
*/
@Data
@AllArgsConstructor
static class Programmer implements Runnable {
private String name;
private String likedCup;
@Override
public void run() {
changeCup();
System.out.println(name + "看着" + gfThreadLocal.get().toString() + ",露出了满意的笑容>>>然后做些羞羞的事");
}
private void changeCup() {
GirlFriend girlFriend = gfThreadLocal.get();
System.out.println(name + "趁着老板打盹,快速拷贝制作了一个" + girlFriend.toString() + ",但是不符合他的style呀");
girlFriend.setCup(this.likedCup);
gfThreadLocal.set(girlFriend);
System.out.println(name + " 经过一番xxxx改造");
}
}
@Data
@AllArgsConstructor
static class GirlFriend {
private String name;
/**
* 罩杯
*/
private String cup;
@Override
public String toString() {
return cup + " cup的" + name;
}
}
}
控制台输出如下
我们看到,小明小李和老板之间的xxx老湿互不影响,各取所需。从而也验证了ThreadLocal其为每个线程提供一个独立的变量副本。
ThreadLocal源码解析请移步至《ThreadLocal源码解析》