最近工作中遇到不少多线程问题,但自己一直对多线程的理解比较表层。没有深入探究。正是最近工作中遇到的问题,致使我深入的去了解多线程安全问题为什么会产生。

    多线程使我们的计算机可以同时运行多个程序,感觉很美好。

    but,多线程的安全问题,到底怎么回事,到底怎么来的,对于有点理想主义的我来说这简直就是BUG。

    网上有不少介绍多线程产生的原因的。我大致看了一遍,感觉都介绍的太粗线条,可能不太适合经验不足者理解。

    so,我就自己整理一下我自己的理解。如有谬误欢迎大家指正和交流。

    首先java 虚拟机中 内存区域分为线程共享和线程私有的两大类。

    

java 线程安全问题样例 java线程安全问题的原因_入栈

现场 画图哈哈。

 java虚拟机在执行字节码指令的时候是什么情况呢?

假设int 类型数据a在线程共享区域目前值为0,java执行以下代码时,需要经过哪些操作呢?

public class Test001

{
	public  int a = 0;

	public void dosomething(){
		a ++ ;
	}

}

我写了一个java类,编译一下



java 线程安全问题样例 java线程安全问题的原因_入栈_02

执行命令javap -l -v Test001.class

我得到了如下结果

java 线程安全问题样例 java线程安全问题的原因_jvm_03

这个是主要执行自增的字节码指令,我们来看下执行过程;

0:将对象本身入栈,这里隐含第一个参数为this;

1:复制栈顶元素,也就是对象的引用;

2:获取栈顶对象属性a的值,并将其入栈;

5:将int型1推送至栈顶;

6:将栈顶两个int类型数据相加,并将结果入栈;

7:将栈顶的值放入对象属性a中;

10:return,不用解释了

我们可以看到简单的一个自增操作,虚拟机要执行的指令却不止一个。

在这一组指令执行过程中,cpu是有可能切换线程的,如果在当前线程t1被挂起之后其他线程修改了这个对象的a属性值,那么恢复线程执行时t1线程将会覆盖其他线程已经修改过的值。


所以,,线程安全问题就是这么产生的了。

理解了怎么产生的就更容易解决如何避免线程安全问题了。