概述
前面几篇博客我们介绍了 java 代码中如何创建并启动线程。而多线程并发在提高效率的同时也带来了线程安全性问题,本篇博客我们主要整理一下java对象和线程安全性问题的联系。
Java对象与线程安全
本篇博客从以下四个模块展开:
- 线程安全问题产生的原因
- 线程安全与全局变量
- 线程安全与局部变量
- 线程安全与其他资源
1、线程安全问题产生的原因
之前的多线程博客中我们提到:如果存在多个线程同时写一块内存空间,就可能产生线程安全问题。对应到 java 代码中,也就是说:如果存在多个线程同时写某个对象值,就可能产生线程安全问题。
下面我们看一个简单的代码:
public class Demo {
private int value = 0;
public void addValue(int num) {
this.value = this.value + num;
}
}
在上述代码中,如果存在多个线程同时调用 addValue() 方法,我们就无法确定结果具体的值,可能是线程1操作的结果,也可以是线程2操作的结果,还可能是两个线程共同操作的结果。我们的目标应该是两个线程共同操作的结果,但现在结果无法确定,也就是说可能造成线程安全问题。
看到这里大家可能会有疑问:简单的一行代码,为什么也存在线程安全问题呢?
原因是这样的:JAVA 不同于C语言编译之后就可以被计算机执行,JAVA 代码首先需要通过编译器编译为 .class 类型,然后被 jvm 解释为当前操作系统能够理解的机器语言,也就是说:操作系统层面执行的指令和我们写的代码是完全不同的,简单的一行 java 代码最终在操作系统层面可能需要运行多条指令。
回到上述代码,addValue() 方法中的代码 this.value = this.value + num 实际上在操作系统中被分解为以下三步:
从内存中读取