Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
b42d76b
“无限循环”打错为“无线循环”
Ryze-Zhao Aug 19, 2019
5ec9e60
修改错别字
Aug 19, 2019
85078eb
Update Atomic.md
chengchena Aug 19, 2019
e9e4b75
Merge pull request #445 from Ryze-Zhao/patch-1
Snailclimb Aug 19, 2019
c74b992
Merge pull request #446 from dgqypl/JG-Mew151-branch
Snailclimb Aug 19, 2019
2ae5a85
Merge pull request #447 from chengchena/patch-2
Snailclimb Aug 19, 2019
e5fd8df
Create RestControllerVS Controller.md
Snailclimb Aug 20, 2019
d0a85ba
Delete RestControllerVS Controller.md
Snailclimb Aug 20, 2019
ba4340e
Create RestControllerVSController.md
Snailclimb Aug 20, 2019
7b0756a
Update README.md
Snailclimb Aug 20, 2019
d5dd6a1
Update Java内存区域.md
LicoCode Aug 21, 2019
034a844
修改错别字
jimmy-han Aug 21, 2019
c1d69e7
Merge pull request #448 from LicoCode/patch-1
Snailclimb Aug 21, 2019
b863b44
Merge pull request #450 from jimmy-han/patch-fix-typo
Snailclimb Aug 21, 2019
cf2e639
refractor:optimize file
Snailclimb Aug 21, 2019
8705227
Update README.md
Snailclimb Aug 21, 2019
27f8743
Update SpringInterviewQuestions.md
Snailclimb Aug 24, 2019
2bab595
Update SpringInterviewQuestions.md
Snailclimb Aug 24, 2019
2c1fa99
Update README.md
Snailclimb Aug 24, 2019
2d57ac9
Delete RestControllerVSController.md
Snailclimb Aug 24, 2019
d8d16a7
Update SpringInterviewQuestions.md
Snailclimb Aug 24, 2019
79cfdc1
Update HashMap.md
Snailclimb Aug 24, 2019
2c5a060
Update README.md
Snailclimb Aug 25, 2019
c3b7445
Update 美团面试常见问题总结.md
Snailclimb Aug 26, 2019
1ecb96d
Update Shell.md
Snailclimb Aug 26, 2019
9ff5f01
Update 干货:计算机网络知识总结.md
ImmortalCountry Aug 27, 2019
4286fc0
Update README.md
Snailclimb Aug 28, 2019
1e1ded7
Create springboot-questions.md
Snailclimb Aug 28, 2019
8596a0b
Merge pull request #457 from ImmortalCountry/master
Snailclimb Aug 29, 2019
3ef9627
Update springboot-questions.md
Snailclimb Aug 29, 2019
5720352
Update MySQL Index.md
imhansai Aug 30, 2019
4850fba
Merge pull request #459 from hanandjun/patch-2
Snailclimb Sep 2, 2019
2771573
Update Redis.md
Snailclimb Sep 2, 2019
9088399
Update SpringInterviewQuestions.md
Snailclimb Sep 3, 2019
16831e7
修改错别字,去掉多余空格
Sep 4, 2019
80b40be
修改“符合”为"复合"
Sep 4, 2019
bdacabb
Merge pull request #462 from dgqypl/JG-Mew151-branch
Snailclimb Sep 5, 2019
101e1a8
Merge pull request #463 from fpGHwd/patch-1
Snailclimb Sep 5, 2019
5ea438d
docs/java/Java疑难点.md line:65 " == "符号与md语法中的高亮语法冲突,造成歧义
Isolation-Lee Sep 9, 2019
9197868
修改错别字
Sep 9, 2019
7722147
Merge pull request #470 from dgqypl/JG-Mew151-branch
Snailclimb Sep 11, 2019
44a3a70
Merge pull request #469 from Isolation-Lee/master
Snailclimb Sep 11, 2019
9753c38
Create 公众号历史文章汇总.md
Snailclimb Sep 10, 2019
e3ad38a
Update Java基础知识.md
Snailclimb Sep 11, 2019
338662e
Update springboot-questions.md
Snailclimb Sep 11, 2019
94b9948
Update Redis.md
Snailclimb Sep 11, 2019
5140c0e
修改错别字
kevinwang0224 Sep 12, 2019
08b820e
Update SpringInterviewQuestions.md
Snailclimb Sep 15, 2019
e94679c
Update SpringInterviewQuestions.md
Snailclimb Sep 15, 2019
e5df8a6
修复错别字,“参加”修改为“参考”
iceqing Sep 15, 2019
d42d4c1
Update SpringInterviewQuestions.md
Snailclimb Sep 16, 2019
b275a98
Update README.md
Snailclimb Sep 16, 2019
3eda389
Merge pull request #472 from kevinwang0224/patch-5
Snailclimb Sep 16, 2019
d9732e1
Merge pull request #475 from iceqing/master
Snailclimb Sep 16, 2019
3bb6f59
Update Java内存区域.md
Snailclimb Sep 16, 2019
d195257
Update ThredLocal.md
Snailclimb Sep 16, 2019
e8dcd0d
错别字勘误
Isolation-Lee Sep 17, 2019
7e2b3e0
Update SpringInterviewQuestions.md
Snailclimb Sep 17, 2019
156befe
Test Backtracking NQueens
hunghv-0939 Sep 19, 2019
5c4413a
Update SpringInterviewQuestions.md
Snailclimb Sep 20, 2019
41fdc30
Update SpringInterviewQuestions.md
Snailclimb Sep 21, 2019
01ac482
Update README.md
Snailclimb Sep 24, 2019
baf3989
Update Git.md
Snailclimb Sep 24, 2019
835dcaa
Merge pull request #478 from Isolation-Lee/master
Snailclimb Sep 26, 2019
da2dca4
Merge pull request #481 from hunghv-0939/hunghv0939
Snailclimb Sep 26, 2019
9618b37
Update README.md
Snailclimb Sep 27, 2019
c5a96c4
Delete test_backtracking_nqueen.jav
Snailclimb Sep 27, 2019
f8e493d
feat:add authority-certification
Snailclimb Sep 27, 2019
d7c984b
Update basis-of-authority-certification.md
Snailclimb Sep 27, 2019
e8fe9b6
Update basis-of-authority-certification.md
Snailclimb Sep 28, 2019
3e7c312
Update basis-of-authority-certification.md
Snailclimb Sep 29, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 22 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,6 @@
<a href="#投稿"><img src="https://img.shields.io/badge/support-投稿-critical.svg" alt="投稿"></a>
</p>

<h2 align="center">Special Sponsors</h2>
<p align="center">
<!--
<a href="https://www.aliyun.com/acts/hi618/index?userCode=hf47liqn" target="_blank">
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/阿里云外投-1600-300.png" width="390px" height="70px" alt="阿里云618 2折起!"/>
</a>
-->
<a href="https://coding.net/?utm_source=JavaGuide" target="_blank">
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/006rNwoDgy1g2dw5gau7nj30eg02vwfr.jpg" alt="零成本开启敏捷研发" height="70px" width="390px"/>
</a>
</p>

推荐使用 https://snailclimb.top/JavaGuide/ 在线阅读(访问速度慢的话,请使用 https://snailclimb.gitee.io/javaguide ),在线阅读内容本仓库同步一致。这种方式阅读的优势在于:有侧边栏阅读体验更好,Gitee pages 的访问速度相对来说也比较快。

## 目录
Expand All @@ -50,8 +38,9 @@
- [MySQL](#mysql)
- [Redis](#redis)
- [系统设计](#系统设计)
- [设计模式(工厂模式、单例模式 ... )](#设计模式)
- [常用框架(Spring、Zookeeper ... )](#常用框架)
- [权限认证](#权限认证)
- [设计模式(工厂模式、单例模式 ... )](#设计模式)
- [数据通信(消息队列、Dubbo ... )](#数据通信)
- [网站架构](#网站架构)
- [面试指南](#面试指南)
Expand All @@ -61,7 +50,7 @@
- [工具](#工具)
- [Git](#git)
- [Docker](#Docker)
- [资料](#资料)
- [资源](#资源)
- [书单](#书单)
- [Github榜单](#Github榜单)
- [待办](#待办)
Expand Down Expand Up @@ -110,6 +99,7 @@

* [Java 8 新特性总结](docs/java/What's%20New%20in%20JDK8/Java8Tutorial.md)
* [Java 8 学习资源推荐](docs/java/What's%20New%20in%20JDK8/Java8教程推荐.md)
* [Java8 forEach 指南](docs/java/What's%20New%20in%20JDK8/Java8foreach指南.md)

### 编程规范

Expand Down Expand Up @@ -162,10 +152,6 @@

## 系统设计

### 设计模式

- [设计模式系列文章](docs/system-design/设计模式.md)

### 常用框架

#### Spring
Expand All @@ -175,12 +161,23 @@
- [Spring中bean的作用域与生命周期](docs/system-design/framework/spring/SpringBean.md)
- [SpringMVC 工作原理详解](docs/system-design/framework/spring/SpringMVC-Principle.md)
- [Spring中都用到了那些设计模式?](docs/system-design/framework/spring/Spring-Design-Patterns.md)
- [SpringBoot 使用指南](https://github.com/Snailclimb/springboot-guide)
-

#### ZooKeeper

- [ZooKeeper 相关概念总结](docs/system-design/framework/ZooKeeper.md)
- [ZooKeeper 数据模型和常见命令](docs/system-design/framework/ZooKeeper数据模型和常见命令.md)

### 权限认证

- [权限认证基础:区分Authentication,Authorization以及Cookie、Session、Token](docs/system-design/authority-certification/basis-of-authority-certification.md)
- [适合初学者入门 Spring Security With JWT 的 Demo](https://github.com/Snailclimb/spring-security-jwt-guide)

### 设计模式

- [设计模式系列文章](docs/system-design/设计模式.md)

### 数据通信

- [数据通信(RESTful、RPC、消息队列)相关知识点总结](docs/system-design/data-communication/summary.md)
Expand Down Expand Up @@ -231,13 +228,17 @@
* [Docker 入门](docs/tools/Docker.md)
* [一文搞懂 Docker 镜像的常用操作!](docs/tools/Docker-Image.md)

## 资料
## 资源

### 书单

- [Java程序员必备书单](docs/data/java-recommended-books.md)

### Github榜单
### 实战项目推荐

- [onemall](https://github.com/YunaiV/onemall) : mall 商城,基于微服务的思想,构建在 B2C 电商场景下的项目实战。核心技术栈,是 Spring Boot + Dubbo 。未来,会重构成 Spring Cloud Alibaba 。

### Github 历史榜单

- [Java 项目月榜单](docs/github-trending/JavaGithubTrending.md)

Expand Down Expand Up @@ -283,7 +284,7 @@ Markdown 格式参考:[Github Markdown格式](https://guides.github.com/featur

添加我的微信备注“Github”,回复关键字 **“加群”** 即可入群。

![我的微信](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/wechat1.jpg)
![个人微信](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/wechat3.jpeg)

### Contributor

Expand Down
2 changes: 1 addition & 1 deletion docs/database/MySQL Index.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ select * from user where city=xx ; // 无法命中索引

冗余索引指的是索引的功能相同,能够命中 就肯定能命中 ,那么 就是冗余索引如(name,city )和(name )这两个索引就是冗余索引,能够命中后者的查询肯定是能够命中前者的 在大多数情况下,都应该尽量扩展已有的索引而不是创建新索引。

MySQLS.7 版本后,可以通过查询 sys 库的 `schema_redundant_indexes` 表来查看冗余索引
MySQL 5.7 版本后,可以通过查询 sys 库的 `schema_redundant_indexes` 表来查看冗余索引

### Mysql如何为表字段添加索引???

Expand Down
6 changes: 5 additions & 1 deletion docs/database/Redis/Redis.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

**高性能:**

假如用户第一次访问数据库中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据存在数缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了。操作缓存就是直接操作内存,所以速度相当快。如果数据库中的对应数据改变的之后,同步改变缓存中相应的数据即可!
假如用户第一次访问数据库中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据存在缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了。操作缓存就是直接操作内存,所以速度相当快。如果数据库中的对应数据改变的之后,同步改变缓存中相应的数据即可!

![](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-9-24/54316596.jpg)

Expand Down Expand Up @@ -251,6 +251,10 @@ Redis 通过 MULTI、EXEC、WATCH 等命令来实现事务(transaction)功能。

在传统的关系式数据库中,常常用 ACID 性质来检验事务功能的可靠性和安全性。在 Redis 中,事务总是具有原子性(Atomicity)、一致性(Consistency)和隔离性(Isolation),并且当 Redis 运行在某种特定的持久化模式下时,事务也具有持久性(Durability)。

补充内容:

> 1. redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。(来自[issue:关于Redis事务不是原子性问题](https://github.com/Snailclimb/JavaGuide/issues/452) )

### 缓存雪崩和缓存穿透问题解决方案

**缓存雪崩**
Expand Down
6 changes: 3 additions & 3 deletions docs/database/一千行MySQL命令.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ SHOW VARIABLES -- 显示系统变量信息
-- 查看所有表
SHOW TABLES[ LIKE 'pattern']
SHOW TABLES FROM 库名
-- 查看表机构
-- 查看表结构
SHOW CREATE TABLE 表名 (信息更详细)
DESC 表名 / DESCRIBE 表名 / EXPLAIN 表名 / SHOW COLUMNS FROM 表名 [LIKE 'PATTERN']
SHOW TABLE STATUS [FROM db_name] [LIKE 'pattern']
Expand Down Expand Up @@ -363,7 +363,7 @@ set(val1, val2, val3...)
字段不能再分,就满足第一范式。
-- 2NF, 第二范式
满足第一范式的前提下,不能出现部分依赖。
消除符合主键就可以避免部分依赖。增加单列关键字。
消除复合主键就可以避免部分依赖。增加单列关键字。
-- 3NF, 第三范式
满足第二范式的前提下,不能出现传递依赖。
某个字段依赖于主键,而有其他字段依赖于该字段。这就是传递依赖。
Expand Down Expand Up @@ -590,7 +590,7 @@ CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] VIEW view_name
```mysql
事务是指逻辑上的一组操作,组成这组操作的各个单元,要不全成功要不全失败。
- 支持连续SQL的集体成功或集体撤销。
- 事务是数据库在数据晚自习方面的一个功能
- 事务是数据库在数据完整性方面的一个功能
- 需要利用 InnoDB 或 BDB 存储引擎,对自动提交的特性支持完成。
- InnoDB被称为事务安全型引擎。
-- 事务开启
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
request.getRequestDispatcher("login_success.jsp").forward(request, response);
```

**重定向(Redirect)** 是利用服务器返回的状态吗来实现的。客户端浏览器请求服务器的时候,服务器会返回一个状态码。服务器通过HttpServletRequestResponse的setStatus(int status)方法设置状态码。如果服务器返回301或者302,则浏览器会到新的网址重新请求该资源。
**重定向(Redirect)** 是利用服务器返回的状态码来实现的。客户端浏览器请求服务器的时候,服务器会返回一个状态码。服务器通过HttpServletRequestResponse的setStatus(int status)方法设置状态码。如果服务器返回301或者302,则浏览器会到新的网址重新请求该资源。

1. **从地址栏显示来说**:forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器。浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址。redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址。所以地址栏显示的是新的URL。
2. **从数据共享来说**:forward:转发页面和转发到的页面可以共享request里面的数据。redirect:不能共享数据。
Expand Down
4 changes: 2 additions & 2 deletions docs/java/Java基础知识.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
- [Throwable类常用方法](#throwable类常用方法)
- [异常处理总结](#异常处理总结)
- [33 Java序列化中如果有些字段不想进行序列化,怎么办?](#33-java序列化中如果有些字段不想进行序列化怎么办)
- [34 获取用键盘输入常用的的两种方法](#34-获取用键盘输入常用的的两种方法)
- [34 获取用键盘输入常用的两种方法](#34-获取用键盘输入常用的两种方法)
- [35 Java 中 IO 流分为几种?BIO,NIO,AIO 有什么区别?](#35-java-中-io-流分为几种bionioaio-有什么区别)
- [java 中 IO 流分为几种?](#java-中-io-流分为几种)
- [BIO,NIO,AIO 有什么区别?](#bionioaio-有什么区别)
Expand Down Expand Up @@ -123,7 +123,7 @@ JRE 是 Java运行时环境。它是运行已编译 Java 程序所需的所有

**总结:**

1. Oracle JDK版本将每三年发布一次,而OpenJDK版本每三个月发布一次;
1. Oracle JDK大概每6个月发一次主要版本,而OpenJDK版本大概每三个月发布一次。但这不是固定的,我觉得了解这个没啥用处。详情参见:https://blogs.oracle.com/java-platform-group/update-and-faq-on-the-java-se-release-cadence。
2. OpenJDK 是一个参考模型并且是完全开源的,而Oracle JDK是OpenJDK的一个实现,并不是完全开源的;
3. Oracle JDK 比 OpenJDK 更稳定。OpenJDK和Oracle JDK的代码几乎相同,但Oracle JDK有更多的类和一些错误修复。因此,如果您想开发企业/商业软件,我建议您选择Oracle JDK,因为它经过了彻底的测试和稳定。某些情况下,有些人提到在使用OpenJDK 可能会遇到了许多应用程序崩溃的问题,但是,只需切换到Oracle JDK就可以解决问题;
4. 在响应性和JVM性能方面,Oracle JDK与OpenJDK相比提供了更好的性能;
Expand Down
11 changes: 5 additions & 6 deletions docs/java/Java疑难点.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

- [1. 基础](#1-基础)
- [1.1. 正确使用 equals 方法](#11-正确使用-equals-方法)
- [1.2. 整形包装类值的比较](#12-整形包装类值的比较)
- [1.2. 整型包装类值的比较](#12-整型包装类值的比较)
- [1.3. BigDecimal](#13-bigdecimal)
- [1.3.1. BigDecimal 的用处](#131-bigdecimal-的用处)
- [1.3.2. BigDecimal 的大小比较](#132-bigdecimal-的大小比较)
Expand Down Expand Up @@ -62,12 +62,12 @@ public static boolean equals(Object a, Object b) {
Reference:[Java中equals方法造成空指针异常的原因及解决方案](https://blog.csdn.net/tick_tock97/article/details/72824894)

- 每种原始类型都有默认值一样,如int默认值为 0,boolean 的默认值为 false,null 是任何引用类型的默认值,不严格的说是所有 Object 类型的默认值。
- 可以使用==或者!=操作来比较null值,但是不能使用其他算法或者逻辑操作。在Java中`null==null`将返回true。
- 可以使用 == 或者 != 操作来比较null值,但是不能使用其他算法或者逻辑操作。在Java中`null == null`将返回true。
- 不能使用一个值为null的引用类型变量来调用非静态方法,否则会抛出异常

## 1.2. 整形包装类值的比较
## 1.2. 整型包装类值的比较

所有整形包装类对象值得比较必须使用equals方法
所有整型包装类对象值的比较必须使用equals方法

先看下面这个例子:

Expand Down Expand Up @@ -150,8 +150,7 @@ Reference:《阿里巴巴Java开发手册》

比如我们如果自定义了一个Student类,其中有一个属性是成绩score,如果用Integer而不用int定义,一次考试,学生可能没考,值是null,也可能考了,但考了0分,值是0,这两个表达的状态明显不一样.

**说明** :POJO 类属性没有初值是提醒使用者在需要使用时,必须自己显式地进行赋值,任何 NPE 问题,或
者入库检查,都由使用者来保证。
**说明** :POJO 类属性没有初值是提醒使用者在需要使用时,必须自己显式地进行赋值,任何 NPE 问题,或者入库检查,都由使用者来保证。

**正例** : 数据库的查询结果可能是 null,因为自动拆箱,用基本数据类型接收有 NPE 风险。

Expand Down
2 changes: 1 addition & 1 deletion docs/java/Multithread/AQS.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效

### 2 AQS 原理

> 在面试中被问到并发知识的时候,大多都会被问到“请你说一下自己对于AQS原理的理解”。下面给大家一个示例供大家参加,面试不是背题,大家一定要加入自己的思想,即使加入不了自己的思想也要保证自己能够通俗的讲出来而不是背出来。
> 在面试中被问到并发知识的时候,大多都会被问到“请你说一下自己对于AQS原理的理解”。下面给大家一个示例供大家参考,面试不是背题,大家一定要加入自己的思想,即使加入不了自己的思想也要保证自己能够通俗的讲出来而不是背出来。

下面大部分内容其实在AQS类注释上已经给出了,不过是英语看着比较吃力一点,感兴趣的话可以看看源码。

Expand Down
4 changes: 2 additions & 2 deletions docs/java/Multithread/Atomic.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是
**引用类型**

- AtomicReference:引用类型原子类
- AtomicStampedReference:原子更新引用类型里的字段原子类
- AtomicReferenceFieldUpdater:原子更新引用类型里的字段
- AtomicMarkableReference :原子更新带有标记位的引用类型

**对象的属性修改类型**
Expand Down Expand Up @@ -553,4 +553,4 @@ class User {

**Java工程师必备学习资源:** 一些Java工程师常用学习资源公众号后台回复关键字 **“1”** 即可免费无套路获取。

![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png)
![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png)
14 changes: 13 additions & 1 deletion docs/java/Multithread/ThredLocal.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,19 @@ ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;

通过上面这些内容,我们足以通过猜测得出结论:**最终的变量是放在了当前线程的 `ThreadLocalMap` 中,并不是存在 `ThreadLocal` 上,ThreadLocal 可以理解为只是ThreadLocalMap的封装,传递了变量值。**

**每个`Thread`中都具备一个`ThreadLocalMap`,而`ThreadLocalMap`可以存储以`ThreadLocal`为key的键值对。这里解释了为什么每个线程访问同一个`ThreadLocal`,得到的确是不同的数值。另外,`ThreadLocal` 是 map结构是为了让每个线程可以关联多个 `ThreadLocal`变量。**
**每个Thread中都具备一个ThreadLocalMap,而ThreadLocalMap可以存储以ThreadLocal为key的键值对。** 比如我们在同一个线程中声明了两个 `ThreadLocal` 对象的话,会使用 `Thread`内部都是使用仅有那个`ThreadLocalMap` 存放数据的,`ThreadLocalMap`的 key 就是 `ThreadLocal`对象,value 就是 `ThreadLocal` 对象调用`set`方法设置的值。`ThreadLocal` 是 map结构是为了让每个线程可以关联多个 `ThreadLocal`变量。这也就解释了ThreadLocal声明的变量为什么在每一个线程都有自己的专属本地变量。

```java
public class Thread implements Runnable {
......
//与此线程有关的ThreadLocal值。由ThreadLocal类维护
ThreadLocal.ThreadLocalMap threadLocals = null;

//与此线程有关的InheritableThreadLocal值。由InheritableThreadLocal类维护
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
......
}
```

`ThreadLocalMap`是`ThreadLocal`的静态内部类。

Expand Down
Loading