阅读 57

【弄nèng - 化繁为简】ThreadLocal原理与使用

一. ThreadLocal

面试官经常问:“说说你对ThreadLocal的理解吧” 我们背诵的答案:

线程同步机制是多个线程共享同一个变量,而ThreadLocal是为每个线程创建一个单独的变量副本,每个线程都可以改变自己的变量副本而不影响其它线程所对应的副本

说白了就是线程级别的局部变量,内部是ThreadLocalMap结构,每个线程内部都存在一个局部变量ThreadLocal.ThreadLocalMap threadLocals = null;,ThreadLocal的get,set实际操作的都是线程的局部变量threadLocals 。

Thread变量定义

class Thread implements Runnable {        /* ThreadLocal values pertaining to this thread. This map is maintained      * by the ThreadLocal class. */     ThreadLocal.ThreadLocalMap threadLocals = null;     /*      * InheritableThreadLocal values pertaining to this thread. This map is      * maintained by the InheritableThreadLocal class.      */     ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; 复制代码

ThreadLocal的API

方法名说明
get()返回此线程局部变量的当前线程副本中的值
set(T value)将线程局部变量当前副本中的值设置为指定值
remove()移除此线程局部变量当前副本中的值

get,set源码

 public void set(T value) {         Thread t = Thread.currentThread();         ThreadLocalMap map = getMap(t);         if (map != null)             map.set(this, value);         else             createMap(t, value);     }      public T get() {         Thread t = Thread.currentThread();         ThreadLocalMap map = getMap(t);         if (map != null) {             ThreadLocalMap.Entry e = map.getEntry(this);             if (e != null) {                 @SuppressWarnings("unchecked")                 T result = (T)e.value;                 return result;             }         }         return setInitialValue();     } ThreadLocalMap getMap(Thread t) {         return t.threadLocals;     } 复制代码

可以发现,每个线程中都有一个变量ThreadLocal.ThreadLocalMap,当执行get,set方法时都在操作当前线程的threadLocals变量,所以多个线程互不干扰。

示例

代码

public class ThreadLocalDemo {     public static final ThreadLocal userThreadLocal = new ThreadLocal();     public static final Map userMap = new HashMap<>();     public static void main(String[] args) throws InterruptedException {         for (int i=0;i<2;i++) {             // 睡一会             Thread.sleep(3000);             new Thread(new Runnable() {                 @Override                 public void run() {                     System.out.println("userThreadLocal:" + Thread.currentThread().getName() + ":" + userThreadLocal.get());                     userThreadLocal.set(Math.random() * 100);                     System.out.println("userThreadLocal:" + Thread.currentThread().getName() + ":" + userThreadLocal.get());                     System.out.println("----------------");                     System.out.println("userMap:" + Thread.currentThread().getName() + ":" + userMap.get("a"));                     userMap.put("a", Math.random() * 100);                     System.out.println("userMap:" + Thread.currentThread().getName() + ":" + userMap.get("a"));                     System.out.println("====================================================");                 }             }).start();         }     } } 复制代码

输出 在这里插入图片描述 分别定义了ThreadLocal 和Map变量,观察两个线程执行的区别,Map变量在第二个线程中获取到了第一个线程的值,而ThreadLocal 变量没有


作者:司马缸砸缸了
链接:https://juejin.cn/post/7028766461275406350


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐