java并发编程实践 3.3 线程封闭

缘起

《java并发编程实践》 3.3节

分析

我们在讨论同步之前,先考虑一下可以不同步的情况. 因为如果线程之间可以不用同步的话,效率是最高的. 线程不同步常用的两种手段是

  1. 线程封闭(即这个变量其实只属于一根线程,则就不存在并发)
  2. 对象本身不变(immutable),不管多少线程来读,读到的都是一样的

本节介绍的是线程封闭的情形. 而线程封闭可以有三种手段实现

  1. Ad hoc
  2. 栈限制
  3. ThreadLocal

Ad hoc

所谓Ad hoc 的含义是 “维护线程封闭性的职责完全由程序实现来承担”. 意思不好理解. 但是Ad hoc有一个特例——volatile关键字,只要你能保证众多线程中只有一根线程写该volatile变量,其余都是读(这不就是volatile关键字的应用场景么?) 则就能保证对该变量的并发操作是线程安全的. 注意,为什么只允许一根线程? 因为volatile关键字不保证原子性,只保证可见性.

栈限制

栈限制的含义就是这个变量仅仅是在方法内部出现(即作为线程的本地变量). 而不能作为属性. 但是这句话对于变量是基本类型变量是没有问题的. 对于引用类型变量就不完全对了——因为你还得保证该引用不会被发布(发布的概念见前一节)出去(java中都是值传递,没有引用传递).如果发布出去的话,则栈限制对于引用变量就是无效的. 所以相比于基本类型的天生栈限制,引用类型的栈限制需要程序员自己注意更多.

ThreadLocal

参见【1】

参考

【1】https://yfsyfs.github.io/2019/06/27/ThreadLocal-%E6%BA%90%E7%A0%81%E8%A7%A3%E8%AF%BB/