在上文中,《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高质量代码编写方面的技巧,请联系我们哦。

Java代码质量改进之:使用ThreadLocal维护线程内部变量的更多相关文章

  1. [改善Java代码]不使用stop方法停止线程

    线程启动完毕后,在运行可能需要终止,Java提供的终止方法只有一个stop,但是不建议使用此方法,因为它有以下三个问题: (1)stop方法是过时的 从Java编码规则来说,已经过时的方式不建议采用. ...

  2. Java并发(二十):线程本地变量ThreadLocal

    ThreadLocal是一个本地线程副本变量工具类. 主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不同的 ...

  3. Java中的闪光点:ThreadLocal是线程Thead的局部变量,可替代同步机制的设计,值得学习和研究

    线程局部变量ThreadLocal,是Java支持的一种线程安全机制,目的是解决多线程的并发问题. 具体来讲,就是多个线程访问该实例对象的变量时,该实例对象将其存储为键值对的形式,保证各个线程(键)分 ...

  4. 使用ThreadLocal在线程内部传递数据

    最近在项目中使用到了JDK提供的线程池,遇到了在多线程环境下在线程内部共享数据的问题 使用ThreadLocal 来解决线程内部共享数据的问题 定义BO package com.unicom.uclo ...

  5. java线:辛格尔顿隐藏ThreadLocal实现线程数据共享

    效果图分享: A和B需要共享同一线程,还有一组的相同A和B共享还有一组线程,两组相互之间不受影响. 代码: package cn.itcast.lesson6; import java.util.Ra ...

  6. Java代码质量改进之:同步对象的选择

    在Java中,让线程同步的一种方式是使用synchronized关键字,它可以被用来修饰一段代码块,如下: synchronized(被锁的同步对象) { // 代码块:业务代码 } 当synchro ...

  7. Java 200+ 面试题补充 ThreadLocal 模块

    让我们每天都有进步,老王带你打造最全的 Java 面试清单,认真把一件事做到极致. 本文是前文<Java 最常见的 200+ 面试题>的第一个补充模块. 1.ThreadLocal 是什么 ...

  8. java笔记--用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程

    用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程 ThreadLocal在我的笔记"关于线程同步"的第5种方式里面有介绍,这里就不多说了. ...

  9. Java ThreadLocal (Java代码实战-006)

    ThreadLocal解决什么问题 由于 ThreadLocal 支持范型,如 ThreadLocal< StringBuilder >,为表述方便,后文用 变量 代表 ThreadLoc ...

随机推荐

  1. flask的orm框架(SQLAlchemy)-一对多查询以及多对多查询

    一对多,多对多是什么? 一对多.例如,班级与学生,一个班级对应多个学生,或者多个学生对应一个班级. 多对多.例如,学生与课程,可以有多个学生修同一门课,同时,一门课也有很多学生. 一对多查询 如果一个 ...

  2. Unicode转义序列

    声明: web前端学习笔记,欢迎大神指点.联系QQ:1522025433. Javascipt 定义了一种特殊序列,使用6位ASCII字符代表任意16Unicode内码.这些Unicode转义序列均以 ...

  3. python 全栈开发,Day133(玩具与玩具之间的对话,基于jieba gensim pypinyin实现的自然语言处理,打包apk)

    先下载github代码,下面的操作,都是基于这个版本来的! https://github.com/987334176/Intelligent_toy/archive/v1.6.zip 注意:由于涉及到 ...

  4. Entity Framework解决sql 条件拼接,完美解决 解决 不支持 LINQ 表达式节点类型“Invoke”【转】

    传统的操作数据库方式,筛选数据需要用StringBuilder拼接一大堆的WHERE子句. 在Entity Framework中,代码稍有不慎就会造成巨大性能消耗,如: using(var db=ne ...

  5. 利用jQuery-UI和jsPlumb实现拖拽连接模型

    简介 之前公司需要做一个自定义数据搜索模型的功能,大体是这样的:左边显示的每一个模型对应于数据库中的一个表,把左边的模型拉入右边的容器内,会显示这个模型(也就是表)下的列信息,然后通过连线确定各独立的 ...

  6. P1032 字串变换 字符串BFS

    题目描述 已知有两个字串A,BA,B及一组字串变换的规则(至多66个规则): A_1A1​ ->B_1B1​ A_2A2​ -> B_2B2​ 规则的含义为:在 AA中的子串 A_1A1​ ...

  7. python中对变量的作用域LEGB、闭包、装饰器基本理解

    一.作用域 在Python程序中创建.改变.查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域.python的作用域是静态的,在源代码中变量名被赋值的位置决定了该变量 ...

  8. Spring根据包名获取包路径下的所有类

    参考mybatis MapperScannerConfigurer.java 最终找到 Spring的一个类  ClassPathBeanDefinitionScanner.java 参考ClassP ...

  9. shell find

    find   -name april*                     在当前目录下查找以april开始的文件 find    /   -amin    -10     # 查找在系统中最后1 ...

  10. Bootstrap 图片

    摘要: Bootstrap框架对图片样式的支持. <img>类 Bootstrap 提供了对图片应用简单样式的 class. .img-rounded:添加 border-radius:6 ...