jse-1.1.6 线程封闭之threadlocal和栈封闭 【信息】 【思考】 【行动/反馈】 【钩子】 【出处】 【时间】

线程封闭之ThreadLocal和栈封闭

【信息】

线程封闭概念

数据都被封闭在各自的线程中,就不需要同步,这种通过将数据封闭在线程中而避免使用同步的技术称为线程封闭。

具体体现有:

  • ThreadLocal
  • 局部变量

ThreadLocal

是Java里一种特殊的变量

它是一个线程级别的变量,每个线程都有一个ThreadLocal就是每个线程都拥有了自己独立的一个变量,竞争条件被彻底消除了,在并发模式下是绝对安全的变量。

==用法:== ThreadLocal var = new ThreadLocal();

会自动在每个线程上创建一个T的副本,副本之间彼此独立,互不影响。

可以用ThreadLocal存储一些参数,以便在线程中多个方法中使用,用来代替方法传参的做法。

可以理解为,JVM维护了一个Map<Thread, T>,每个线程要用这个T的时候,用当前线程去Map里面取。仅作为一个概念理解

栈封闭

局部变量的固有属性之一就是封闭在线程中。它们位于执行线程的栈中,其他线程无法访问这个栈。

【思考】

线程封闭还有其他方式吗?有哪些场景用?

【行动/反馈】

查下问题:我眼中的线程封闭
线程封闭有哪些实现方式?

1
2
3
4
5
6
7
8
9
1.使用单线程。曲折的可以这么说。

2.多线程环境下,如果能保证通过某种方式访问共享变量的时候是单线程的,也可以实现。

3.Ad-hoc,我的理解是使用程序来保证这种封闭性,这种方式不好,不好写,不好维护。

4.栈封闭,也就是使用局部变量,因为局部变量的特性是属于某个线程的,也就是说线程和线程间的局部变量是独立的。但要防止对象溢出,比如一个方法内对象被发布了,封闭性就被打破。

5使用ThreadLocal。

线程封闭的应用场景

1
2
3
4
5
6
7
8
9
10
11
1.swing的可视化组件和数据模型对象都不是线程安全的,swing通过将他们封闭到Swing的事件分发线程中来实现线程安全。

2.jdbc的connection对象,在服务器应用中,会从连接池中获取jdbc对象,使用对象处理请求,用完后返还给连接池,由于大多数请求(比如servlet)一个请求过来是单线程的同步的方式处理,并且connection返回前连接池不会将该对象分配给其他线程,所以这种连接管理模式在处理请求时隐含的将Connection对象封闭在线程中。

3.(程序控制的例子),如果能保证单线程写入volatile变量,就可以安全的在volatile变量上执行 读-改-写的非原子操作。

4(ThreadLocal)spring?

应用程序框架大量使用了ThreadLocal,J2EE容器将事务上下文与执行中的线程关联起来,当框架判断代码运行的当前是哪个事务时,只需要从这个ThreadLocal对象中读取事务上下文。这样做的好处可以避免运行的过程中需要传递事务上下文,使框架和代码耦合。

5.Integer.toString()方法使用ThreadLocal对象来保存一个12字节大小的缓冲区,因为需要每次临时都创建这样一个临时缓冲区对象,对结果格式化,其实我觉的这种场景利用了ThreadLocal的线程隔离和Map存储数据的特性。

【钩子】

线程封闭 ThreadLocal

【出处】

Java高级开发工程师-线程封闭之ThreadLocal和栈封闭

【时间】

2018-12-27


若涉及版权问题,请及时联系作者删除。

更多精彩文章请关注