线程封闭之ThreadLocal和栈封闭

线程封闭

线程不安全是因为多线程在访问共享的可变数据时,会发生数据的不一致,结果不正确. 实现好的并发是一件困难的事情, 那么如何解决呢,一个是使用同步,但是同步需要占用资源,另外一种方式,如果一个线程访问这个数据,就不会出现问题, 所以很多时候我们都想躲避并发. 避免并发最简单的方法就是线程封闭. 什么是线程封闭; 就是把对象封装到一个线程里,只有这个线程能看到此对象. 那么这个对象就算不是线程安全的也不会出现任何问题.

线程封闭的实现方式

  1. Ad-hoc : 维护线程封闭性的职责完全由程序实现来承担,是非常脆弱的, 因为没有任何一种语言特性, 能将对象封闭到目标线程上.
  2. 栈封闭 : 简单的来说就是局部变量. 多个线程访问一个方法,此方法中的局部变量都会拷贝一份到线程栈中,. 所以局部变量是不被多个线程所共享,也就不会出现并发问题,所以能用局部变量就别用全局变量, 全局变量容易引起并发问题.
  3. ThreadLocal 封闭 : 使用ThreadLocal 是实现线程封闭的最好方法. ThreadLocal 内部维护了一个 Map, Map 的 key 是每个线程对象,而 Map 的值就是我们要封闭的对象(数据) . 每个线程中的对象都对应这 Map 中的一个值, 也就是 ThreadLocal 利用 Map 实现了对象的线程封闭.

ThreadLocal

ThreadLocal 是 Java 中的一种特殊变量
它是一个线程级别的变量,每个线程都有一个 ThreadLocal 就是每个线程都拥有了自己独立的一个变量, 竞争条件被彻底消除了,在并发模式下是绝对安全的变量.
用法: ThreadLocal<T> var=new ThreadLocal<T>();
会自动在每一个线程上创建一个 T 的副本,副本之间彼此独立,互不影响.
可以再 ThreadLocal 中存储一些参数,以便在线程中多个方法中使用, 用来代替方法传参的做法.