Java代码质量改进之:使用ThreadLocal维护线程内部变量
在上文中,《Java代码质量改进之:同步对象的选择》,我们提出了一个场景:火车站有3个售票窗口,同时在售一趟列车的100个座位。我们通过锁定一个靠谱的同步对象,完成了上面的功能。
现在,让我们反过来,每个窗口负责一趟车。比如一号窗口就卖1号列车的票,二号窗口就卖2号列车的票。不过它们需要同时开始卖票。
一:ThreadLocal的最简应用
首先,既然是各卖各的火车了,那么,就不需要同步了。于是代码又回归到:
但是当前的代码肯定是不对的,每个线程访问的都是同一个火车的ticket,并且还会出现超售现象。要保证每new一个窗口出来,就有一趟自己的列车,我们就可以用到ThreadLocal对象了。
让我们首先替换掉ticket变量,改为:
然后,售票的代码改为:
虽然ticket依然是一个static变量,但是,运行程序你会发现,新起一个线程,不同的线程还是会拥有自己的ticket,不会互相干扰。也就是实现了每个窗口卖自己那趟车的目标。
二:ThreadLocal VS 实例变量
每一个程序员都应该是杠精。为什么,因为回过神来的我们发现,只要回到第一段代码中,把ticket中的static去掉,就能达到同样的目的:
试下上面的代码,是不是也能达到各卖各的目的?
我们是脑袋被门板挤了,才想出来一个TheadLocal这样的复杂方案吗?
如果单纯说上面的这段代码,是的。但是,还有很多的场合,是ThreadLocal的用武之处。比如,我们并不永远使用extends Thead的方式来写多线程,我们还可能用implements Runnable的方式来写多线程(ps:还有更多的写法哦),如下:
而在这种情况下,我们就不得不使用TheadLocal了,这里就不放出代码了,大家可以试一下。
甚至,更进一步的,我们是不是能够把ticket这个变量放进方法内部呢,如果放入方法
内部的话,我们同样也是必须要使用ThreadLocal才能达到实现目的,如下:
总之,简单来说:当要运行的代码本身不是很方便访问当前的线程实例的时候,就是ThreadLocal的用武之地。
三:ThreadLocal的应用场景
ThreadLocal有这样一些应用场景,比如连接池管理、会话管理等等。
在连接池的管理中,当我们需要获取一个连接,就应该为每一次获取给出不同的连接。在web应用中,请求是被线程池管理的,也就是说获取连接这个行为不是单线程行为,所以我们最好就要设计成不同的线程不能获取同一个连接,要保证能做到这样,就应该使用ThreadLocal了。
可能有人会表示,那不能设计成实例变量吗?答案是:不能。因为,在web应用中,线程都不是被我们自己管理的,所以,最佳的做法就是使用ThreadLocal。一个标准的做法如下:
最后作为补充,我们再来看看hibernate中ThreadLocal的应用:
以下是广告时间:最课程(http://zuikc.com)正在招收Java就业班学员,如果你想学习更多的Java高质量代码编写方面的技巧,请联系我们哦。
转载于:https://www.cnblogs.com/luminji/p/9419292.html
Java代码质量改进之:使用ThreadLocal维护线程内部变量相关推荐
- java 内部thread_Java代码质量改进之:使用ThreadLocal维护线程内部变量
在上文中,<Java代码质量改进之:同步对象的选择>,我们提出了一个场景:火车站有3个售票窗口,同时在售一趟列车的100个座位.我们通过锁定一个靠谱的同步对象,完成了上面的功能. 现在,让 ...
- [改善Java代码]不使用stop方法停止线程
线程启动完毕后,在运行可能需要终止,Java提供的终止方法只有一个stop,但是不建议使用此方法,因为它有以下三个问题: (1)stop方法是过时的 从Java编码规则来说,已经过时的方式不建议采用. ...
- ThreadLocal应用-使用ThreadLocal做线程缓存变量池
多线程环境下,或者web环境下,可以使用ThreadLocal做变量池用 import java.util.HashMap; import java.util.Map;public abstract ...
- js字符串如何拼接java代码_JS如何定义用字符串拼接的变量
今天在写js的时候碰到了难题,我又一个页面需要生成很多的变量.但是变量的名称是根据参数的不同而区分的. 例如可能需要生成 date_1,date_2,datet_3... (后面的数字是根据参数来的) ...
- Java 200+ 面试题补充 ThreadLocal 模块
让我们每天都有进步,老王带你打造最全的 Java 面试清单,认真把一件事做到极致. 本文是前文<Java 最常见的 200+ 面试题>的第一个补充模块. 1.ThreadLocal 是什么 ...
- Java:多线程(同步死锁、锁原子变量、线程通信、线程池)
5,同步和死锁 5.1,线程同步 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象: 修饰一个方法,被修饰的方法称为同步方法,其作用 ...
- linux用于在固定时间间隔启动,按固定时间间隔在Linux环境中运行java代码
主要分两步:一.在Linux环境中一直运行一个线程.二.如何控制java代码同时执行多个工作线程. 一.可以用Linux中的 nohup 命令,控制该线程就算在终端被关闭或者账户退出之后,继续在后台 ...
- Eclipse解决每次修改java代码或jsp代码服务器重启问题的解决办法
1.面临的问题: Eclipse有点非常不友好,就是不管我怎么修改Java代码,哪怕只有仅仅一行代码都需要重新启动,才能使修改代码生效. 由于我们项目较大,这点严重影响了我的工作效率,本文 ...
- JAVA线程本地变量ThreadLocal和私有变量的区别
ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些. 所以,在Java中编写线程局部变量的代码相对来说要笨 ...
- Java高并发编程详解系列-线程上下文设计模式及ThreadLocal详解
导语 在之前的分享中提到过一个概念就是线程之间的通信,都知道在线程之间的通信是一件很消耗资源的事情.但是又不得不去做的一件事情.为了保证多线程线程安全就必须进行线程之间的通信,保证每个线程获取到的 ...
最新文章
- Battery electric vehicles (BEVs) 快充技术
- 阿里巴巴发布AI养蜂系统
- Nginx+Keepalived+Proxy_Cache 配置高可用集群和高速缓存
- 基于Android设备的Kali Linux渗透测试教程第1章渗透测试
- Boost.Signals2 的多槽 hello world 示例
- 手把手教你把代码丢入github 中
- javascript一些底层方法总结及用法
- 应用程序无法正常启动(0xc000007b)错误的解决
- mybatis注解开发_快速搭建MyBatis开发环境(配置版+注解版)
- mysql报表慢_mysql慢查询日志报表工具mysqlsla
- laravel5.5 Auth门脸类认证
- 对拷 使用scp命令在两台linux上对拷文件或者文件夹
- VSCode 设置为 Monaco字体
- 窦志成:从微软到人大,只为做有温度的AI
- 【STM32】 STM32单片机IO引脚配置方式
- python中oserror_[python] 解决OSError:
- pytorch骚操作之梯度累加,变相增大batch size
- 搭建自己的dns服务器
- 微型计算机的软 硬件组成,微型计算机的软、硬件组成及主要性能指标
- 作业扣最少的分(要选好贪心目标)