「javaSE基础」2018面试-多线程之局部变量ThreadLocal的案例演示

今天主要写一下ThreadLocal对象。文章如有介绍不全的,望多加体谅。

  • ThreadLocal的作用和目的:用于实现线程内的数据共享,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另一个线程运行时又共享另外一份数据。
  • 每个线程调用全局ThreadLocal对象的set方法,在set方法中,首先根据当前线程获取当前线程的ThreadLocal对象,然后往这个map中插入一条记录,key其实就是ThreadLocal对象,value就是各自的set方法传进去的值。也就是每个线程其实都有一份各自独有的ThreadLocalMap对象,该对象的key是ThreadLocal对象,值是用户设置的具体值。该线程结束可以调用ThreadLocal.remove()方法,这样会更快的释放内存,不调用也可以,因为线程结束后可以自动释放相关的ThreadLocal变量。

ThreadLocal的应用场景:

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

ThreadLocal的使用方式:

1.在关联数据类中创建private static ThreadLocal。在下图的例子中,私有静态ThreadLocal实例(serialNum)为调用该类的静态SerialNum.get()方法的每个线程维护了一个“序列号”,该方法返回当前线程的序列号。(线程的序列号在第一次调用SerialNum.get()方法时分配,并在后续的调用中不会更改。)

「javaSE基础」2018面试-多线程之局部变量ThreadLocal的案例演示

案例一

「javaSE基础」2018面试-多线程之局部变量ThreadLocal的案例演示

案例二

2.在Rannable中创建ThreadLocal。

在线程内部创建ThreadLocal,基本步骤如下:

  • 在多线程类(如下例子ThreadLocalTest1)中,创建一个ThreadLocal对象threadXxx,用来保存线程间需要间隔处理的对象xxx;
  • 在ThreadLocalTest1类中,创建一个需要隔离访问的数据的方法getXxx(),在方法中判断,若ThreadLocal对象为null时,应该new()一个隔离访问类型的对象,并强制转换为要应用的类型;
  • 在ThreadLocalTest1类的run()方法中,通过调用getXxx()方法获取需要操作的数据,这样可以保证每个线程对应一个数据对象,在任何时刻都操作的是这个对象。
「javaSE基础」2018面试-多线程之局部变量ThreadLocal的案例演示

案例3

「javaSE基础」2018面试-多线程之局部变量ThreadLocal的案例演示

案例3运行结果

下一篇还将以案例展示多线程数据共享实例。感谢关注转发。

「javaSE基础」2018面试-多线程之局部变量ThreadLocal的案例演示


分享到:


相關文章: