【并发编程】ThreadLocal详解

目录

为什么要有ThreadLocal

ThreadLocal 的使用

实现解析

实现分析

Hash 冲突的解决

开放定址法

链地址法

再哈希法

建立公共溢出区

引发的内存泄漏分析

分析

总结


为什么要有ThreadLocal

我们首先来看看一段最纯粹的原生 JDBC 代码

可以看到, 在使用 JDBC 时, 我们首先要配置后再拿到 JDBC 连接, 然后在增删改查的业务方法中拿到这个连接,并把我们的 SQL 语句交给 JDBC 连接发送到真实的 DB 上执行。

在实际的工作中, 我们不会每次执行 SQL 语句时临时去建立连接,而是会借助数据库连接池, 同时因为实际业务的复杂性, 为了保证数据的一致性, 我们还会引入事务操作,于是上面的代码就会变成:

但是上面的代码包含什么样的问题呢?分析代码我们可以发现, 执行业务方法 business 时, 为了启用事务, 我们从数据库连接池中拿了一个连接, 但是在具体的 insert 方法和 getAll 方法中, 在执行具体的 SQL 语句时, 我们从数据库连接池中拿一个连接, 这就说执行事务和执行 SQL 语句完全是不同的数据库连接, 这会导致什么问题?事务失效了! !数据库执行事务时,事务的开启和提交、语句的执行等都是必须在一个连接中的。实际上,上面的代码要保证数据的一致性, 就必须要启用分布式事务。

怎么解决这个问题呢? 有一个解决思路是,把数据库连接作为方法的参数, 在方法之间进行传递,比如下面这样:

但是我们分析平时我们使用 SSM 的代码会发现,我们在编写数据访问相关代码的时候从来没有把数据库连接作为方法参数进行传递。这意味着, 对 Spring 来说, 在帮我们进行事务托管的时候, 会遇到同样的问题, 那么 Spring 是如何解决这个问题的?

其实稍微分析下 Spring 的事务管理器的代码就能发现端倪,在

org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin 中, 我们会看到如下代码

上面的注释已经很清楚了说明“绑定连接到这个线程”,如何绑定的?继续 深入看看

看来, Spring 是使用一个 ThreadLocal 来实现“绑定连接到线程”的。

现在我们可以对 ThreadLocal 下一个比较确切的定义了

This class provides thread-local variables. These variables differ from their

normal counterparts in that each thread that access

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值