winform线程结束无响应_《详解Java多线程之ThreadLocal》

6e9161aa8652bfabb96e6311063df668.png

面试中我们经常会问到多线程,说到多线程,基本都会被问到多线程的内变量的安全性,多线程的安全性我们使用-ThreadLocal

ThreadLocal原理:

1、多个线程访问同一共享变量时,ThreadLocal类为每个线程提供一份该变量的副本
2、各个线程拥有一份属于自己的变量副本,操作修改的是各自的变量副本,而不会相互影响
3、线程与线程之间,更不会有干扰,每个线程访问的都是自己的ThreadLocalMap

a32658d2cff51a362f74e31769442ef9.png

我们使用多线程还会遇到:Spring的并发问题——有状态Bean和无状态Bean

有状态会话bean

每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每个用户最初都会得到一个初始的bean。简单来说,有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的。

无状态会话bean

bean一旦实例化就被加进会话池中,各个用户都可以共用。即使用户已经消亡,bean 的生命期也不一定结束,它可能依然存在于会话池中,供其他用户调用。由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean。但无状态会话bean 并非没有状态,如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响,这是在实际应用中必须注意的。简单来说,无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象 .不能保存数据,是不变类,是线程安全的。

Spring使用ThreadLocal解决线程安全问题:

1、通常情况下,只有无状态的Bean才可以在多线程环境下共享 2、Spring对一些有状态Bean中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态 3、eg: TransactionSynchronizationManager、 RequestContextHolder、 AopContext 、LocaleContextHolder等等

ThreadLocal在分层架构中的应用:

1、在多层架构中,从接收请求到返回响应所经过的所有程序调用都同属于一个线程 2、在多层架构中,下层通过接口向上层开放功能调用 3、在多层架构中,将一些非线程安全的变量以ThreadLocal存放 4、在同一次请求响应的调用线程中,所有对象所访问的同一ThreadLocal变量都是当前线程所绑定的

2f38027c2efbdfb6b9d37fecaa2eaa28.png

ThreadLocal经常会应用在数据库连接:

原始数据库连接:

1、jdbc连接数据库-问题:线程不安全,一个connection对应的是一个事物,一次、2、2、2、Drivermanager.getConnection(jdbcurl)获得只是一个connection,并不能满足高并发情况;
3、数据库连接优化:
使用数据库连接池,减少线程创建、销毁时间,提高性能
使用threadlocal,保证同一个事务,同一个数据库连接的一致性
pool.getConnection(),都是先从threadlocal获取,如果threadlocal有 值,则用,保证线程里的多个dao操作,用的是 同一个数据库连接,以保证事务;如果没有,则将新的connection放在threadlocal里,再get给到线程

ThreadLocal在Struts2中的应用:

1、ActionContext是Action的上下文,它保存了在Action执行过程中所需的request,session, parameters, locale等对象
2、Struts2会根据每个执行HTTP请求的线程来创建对应的ActionContext,即一个线程有一个唯 一的ActionContext
3、ActionContext是线程安全的,基于ThreadLocal 实现,参考ActionContext源码

ThreadLocal在分布式服务框架中的应用:

1、分布式服务框架对缓存、数据库、消息队列操作进行封装埋点,实现透明的实现服务调用 跟踪

实现方法:

1、在App请求的入口生成唯一requestID,放入ThreadLocal 2、缓存访问层代码埋点,从ThradLocal取出requestID,记录缓存操作耗时 3、数据库访问层代码埋点,从ThradLocal取出requestID,记录数据库操作耗时 4、调用其它微服务 (RPC),将requestID传递到下一个微服务,微服务将接收到的requestID存入ThreadLocal 5、微服务内部的缓存、数据库操作同样记录requestID操作耗时及错误信息 6、消息队列写入、消费代码埋点,传递requestID,记录消息消费耗时

ThreadLocal模式的使用:

使用场景:

在同一个线程的不同开发层次中共享数据。如web应用开发中表示层、业 务层、持久层需要共享数据

使用步骤:

建立一个类,在其中添加一个静态的ThreadLocal变量,使其成为一个共享环境
添加访问静态ThreadLocal的静态方法(设值和取值)

补充信息:

hedwig链式调用(traceid,spanid,parentid)原理:

1、HedwigContextUtil其实是分布式传值对象,HedwigContextUtil封装了一个ThreadLocal对象InvocationContext,该对象封装了全局的参数parentId、reqId 2、服务调用方RequestHandler、HedwigEventEngine设置服务调用方的ClientBizLog,ClientBizLog封装uniqReqId、reqId等信息 3、重要的服务调用方对象DefaultRequest 4、服务提供方LogedWorkerActor、HedwigHessianSkeleton设置服务提供方的ServerBizLog,ServerBizLog封装uniqReqId、reqId等信息

ThreadLocal这集就这样啦。我每天都会更新,希望喜欢的朋友多加关注和点赞的。感谢大家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值