ThreadLocal知识系列总结1

来源:互联网 发布:淘宝小二介入上传凭证 编辑:程序博客网 时间:2024/06/06 19:32

ThreadLocal实现线程范围的共享变量 - 洛克菲勒 - 洛克菲勒家族

上面图片解释处理ThreadLocal的作用和目的:用于实现线程内的数据共享,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另外一份数据。


每个线程调用全局ThreadLocal对象的set方法,就相对于往其内部的map中增加一条记录,key分别是各自的线程,value是各自的set方法传进去的值。在线程结束时可以调用ThreadLocal.clear()方法,这样会更快释放内存,不调用也可以,因为线程结束后也可以自动释放相关的ThreadLocal变量。


ThreadLocal的应用场景:

  1. 订单处理包含一系列操作:减少库存量、增加一条流水台帐、修改总账,这几个操作要在同一个事务中完成,通常也即同一个线程中进行处理,如果累加公司应收款的操作失败了,则应该把前面的操作回滚,否则,提交所有操作,这要求这些操作使用相同的数据库连接对象,而这些操作的代码分别位于不同的模块类中。
  2. 银行转账包含一系列操作:把转出账户的余额减少,把转入账户的余额增加,则两个操作要在同一事务中完成,它们必须使用相同的数据库连接对象,转入和转出操作的代码分别是两个不同的账户对象的方法。
  3. 例如:Strust2的ActionContext,同一段代码被不同线程调用运行时,该代码操作的数据时每个线程各自的状态和数据,对于不同的线程来说,getContext方法拿到的对象都不相同,对同一个线程来说,不管调用getContext方法多少次和在哪个模块中getContext方法,拿到的都是同一个。


实验案例:定义一个全局共享的ThreadLocal变量,然后启动多个线程向该ThreadLocal变量中存储一个随机值,接着各个线程调用另外其他多个类的方法,这多个类的方法中读取这个ThreadLocal变量的值,就可以看到多个类在同一个线程中共享同一份数据。

  实现对ThreadLocal变量的封装,让外界不要直接操作ThreadLocal变量。

对基本类型的数据的封装,这种应用相对很少见。

对对象类型的数据的封装,比较常见,即让某个类针对不同线程分别创建一个独立的实例对象。

 总结:一个ThreadLocal代表一个变量,故其中里只能放一个数据,你有两个变量都要线程范围内共享,则要定义两个ThreadLocal对象。如果有一个百个变量要线程共享呢?那请先定义一个对象来装这一百个变量,然后在ThreadLocal中存储这一个对象。