JUC--变量的线程安全分析
JUC–变量的线程安全分析
背景
-
JUC–变量的线程安全分析
-
博主以黑马JUC进行学习
成员变量和静态变量是否线程安全?
- 如果它们没有共享,则线程安全
- 如果它们被共享了,根据它们的状态是否能够改变,又分两种情况
- 如果只有读操作,则线程安全
- 如果有读写操作,则这段代码是临界区,需要考虑线程安全
局部变量是否线程安全?
- 局部变量是线程安全的
- 但局部变量引用的对象则未必
- 如果该对象没有逃离方法的作用访问,它是线程安全的
- 如果该对象逃离方法的作用范围,需要考虑线程安全
局部变量线程安全分析
1 | public static void test1(){ |
- 每个线程都调用了test1()方法时局部变量i,会在每个线程的栈帧内存中被创建多份,因此不存在共享
- 方法的私有访问修饰符是有意义的,一定程度内可以保护线程安全,因为让继承它的子类不能重写方法
- 或者加入final关键字,防止被子类继承
常见线程安全类
-
String
-
Integer
-
StringBuffer
-
Random
-
Vector
-
Hashtable
-
java.util.concurrent包下的类
-
这里说它们是线程安全的是指,多个线程调用它们同一个实例的某个方法时,是线程安全的。也可以理解为:
- 它们的每个方法是原子的
- 但注意它们多个方法的组合不是原子的
线程安全类方法的组合
- 以下例子不是线程安全的
1 | Hashtable table = new Hashtable(); |
不可变类线程安全性
- String、Integer 等都是不可变类,因为其内部的状态不可以改变,因此它们的方法都是线程安全的
1 | public class Immutable{ |
- String类为什么要加final,因为防止被继承重写,体现了线程安全
- 经典题目:买票问题和转账问题