引言

这三种的关系由于大量的内部类的关系,第一次看的时候还是有点绕的,感觉你是老子的孙子,又是老子的老子。我还是建议你先抛开内部类的关系,把每一个类当作普通类来看到,理解每個类的职责,最后再把内部类放进去考虑这样设计的目的。这里也给大家一个启示,面对复杂的事情的时候,我们需要跳出来,先把问题简单化,大方向把握了,再进一步去细化每一个功能点和设计的艺术。

关系图解

接下来我们看下面一张图

从上图我们可以发现Thread 中持有一个ThreadLocalMap ,这里你可以简单理解为就是持有一个数组,这个数组是Entry 类型的。 Entry 的key 是ThreadLocal 类型的,value 是Object 类型。也就是一个ThreadLocalMap 可以持有多个ThreadLocal。他们是一对多的关系(当然Entry 还涉及到弱引用的技术,这里不展开,不然就没完没了了)

加上内部类的关系

为什么ThreadLocalMap 设计为ThreadLocal 内部类

看到各种内部类是不是有点晕,感觉你是老子的孙子,又是老子的老子,为什么不独立ThreadLocalMap 出来呢?其实这里涉及到内部类起到封装的作用。来,我们看看源码的解析

/**

  • ThreadLocalMap is a customized hash map suitable only for
  • maintaining thread local values. No operations are exported
  • outside of the ThreadLocal class. The class is package private to
  • allow declaration of fields in class Thread. To help deal with
  • very large and long-lived usages, the hash table entries use
  • WeakReferences for keys. However, since reference queues are not
  • used, stale entries are guaranteed to be removed only when
  • the table starts running out of space.
    */
    static class ThreadLocalMap {
    //这里省略其他属性和方法
    }

主要是说明ThreadLocalMap 是一个线程本地的值,它所有的方法都是private 的,也就意味着除了ThreadLocal 这个类,其他类是不能操作ThreadLocalMap 中的任何方法的,这样就可以对其他类是透明的。同时这个类的权限是包级别的,也就意味着只有同一个包下面的类才能引用ThreadLocalMap 这个类,这也是Thread 为什么可以引用ThreadLocalMap 的原因,因为他们在同一个包下面。

虽然Thread 可以引用ThreadLocalMap,但是不能调用任何ThreadLocalMap 中的方法。这也就是我们平时都是通过ThreadLocal 来获取值和设置值,看下以下代码

public class Test {public static void main(String[] args) {ThreadLocal<String> local = new ThreadLocal<>();local.set("hello word");System.out.println(local.get());}
}

但我们调用ThreadLocal 的get 方法的时候,其实我们最后是通过调用ThreadLdocalMap 来获取值的

 public T get() {//这里通过获取当前的线程Thread t = Thread.currentThread();//通过线程来获取ThreadLocalMap ,还记得我们上面说的Thread 里面有一个ThreadLocalMap 属性吗?就是这里用上了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;
}

到这里,读者应该大概明白了,其实ThreadLdocalMap 对使用者来说是透明的,可以当作空气,我们一值使用的都是ThreadLocal,这样的设计在使用的时候就显得简单,然后封装性又特别好。

ThreadLdocalMap 什么时候开始和Thread 进行绑定的呢

在第一次调用ThreadLocal set() 方法的时候开始绑定的,来我们看下set 方法的源码

   public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);else//第一次的时候进来这里,因为ThreadLocalMap 还没和Thread 绑定createMap(t, value);}//这个时候开始创建一个新的ThreadLocalMap 赋值给Thread 进行绑定void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue);}

理清ThreadLocal、ThreadLocalMap、Thread之间的关系相关推荐

  1. Message、Handler、Message Queue、Looper、Thread之间的关系(未完成)

    1. 请解释下在单线程模型中Message.Handler.Message Queue.Looper.Thread之间的关系 2. 什么是IntentService?有何优点? 1) 它是对单线程消息 ...

  2. strongswan libstrongswan scheduler,processor,job,event和thread之间的关系

    目录 scheduler介绍 scheduler调度的event与job的关系 scheduler的主要操作 job又是如何创建的呢? job的执行 scheduler介绍 scheduler使用he ...

  3. 多线程并发可能遇到的问题及Runable和Thread之间的关系

    一.多线程并发可能遇到的问题 多线程并发执行可能会导致一些问题: 安全性问题:在单线程系统上正常运行的代码,在多线程环境中可能会出现意料之外的结果. 活跃性问题:不正确的加锁.解锁方式可能会导致死锁或 ...

  4. cpu、socket、core、thread 等术语之间的关系

    当我们在看技术文档时,经常会发现很多有关 cpu 的术语,比如 cpu.cpu socket.cpu core.hyper-threading 等,乱乱的分不清楚,这篇文章我带大家用三分钟时间,快速的 ...

  5. 一文理清Mybatis中resultType与resultMap之间的关系和使用场景

    点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 1.概述 Mybatis ORM半自动映射框架对java开发工程师来说应该是必会的框架之一. ...

  6. handler和thread之间如何传输数据_HTTP和TCP之间的关系

    在解释两者之间的关系之前,我们必须从宏观的角度了解互联网的整个交互模型.因为当了解互联网在大体上是如何运作时,我们才能了解HTTP和TCP存在的意义,包括他们所要解决的问题是. (此图来自Udacit ...

  7. 正确理解 AsyncTask,Looper,Handler三者之间的关系(基于android 4.0)

    Looper 和Handler 是理解好AsyncTask的一个基础,我们可以先从这里开始,先给出一个主线程和子线程互相通信的例子. 1 package com.example.loopertest; ...

  8. [转]C#综合揭秘——细说进程、应用程序域与上下文之间的关系

    引言 本文主要是介绍进程(Process).应用程序域(AppDomain)..NET上下文(Context)的概念与操作. 虽然在一般的开发当中这三者并不常用,但熟悉三者的关系,深入了解其作用,对提 ...

  9. android 如何获得activity的view对象,Android的Activity 、 Window 、 View之间的关系

    什么是Activity .View . Window? Activity:是Android 四大组件之一, 是存放View对象的容器,也是我们界面的载体,可以用来展示一个界面.它有一个SetConte ...

最新文章

  1. 上海AI高地雏形初现 徐汇区抢占产业潮头
  2. 有没有python与机械结合的工作-Python3从零开始搭建一个语音对话机器人的实现...
  3. PROC简单使用用例--VC连接ORACLE
  4. Springmvc的服务端数据验证-----Hibernate Validator
  5. hibernate5.2.10.Final基本配置
  6. ubuntu 安装星际译王词典
  7. 试试把OJ题意抽象成物理模型(洛谷P1007题题解,Java语言描述)
  8. VC6.0 Raising Error spawning cl.exe solution
  9. Echarts:Vue3中使用Echarts
  10. 关于Kafka幂等producer的讨论
  11. Ubuntu 14.04 安装xvid编码器
  12. 梦幻西游服务器多系统多开,梦幻西游:脚本多开屡禁不止,一组账号告诉你,少去找代练!...
  13. [cf] Codeforces Round #595 (Div. 3) B12 Books Exchange
  14. 车间制造管理系统(上)
  15. 前端求职系列:如何写一份小程序简历(二)
  16. 自学Python day03-if语句
  17. 使用do…while循环语句计算正数5的阶乘
  18. 利用JapiDocs构建java接口文档(无代码侵入性)
  19. 七夕节送女朋友啥礼物好?七夕情人节礼物推荐
  20. #define宏定义是什么?怎么写?一文搞懂。

热门文章

  1. Leetcode-937-Reorder Log Files-(Easy)
  2. [agc016e]poor turkeys
  3. oracle数据库更改字符集
  4. mybatis关系映射(1对1,1对多,多对多)
  5. TypeError: Cannot red property 'style' of null 错误解决
  6. Linq to XML的练习
  7. CUDA Stream流并发性
  8. Ganglia集群监控系统搭建
  9. 科学计算:Python VS. MATLAB(4)----图形系统简介
  10. 初入R语言,绘制heatmap图