首先,我们要清楚java中的内存情况,大略如下,这个大家一般都知道:
1:heap,堆内存,用来存放新创建的类对象,其实就是存储对象的成员变量值、变量类型、对象类型标记;
2:stack,栈内存,用来存储局部变量、对对象的引用等;
3:data segment,数据区,在这个区主要存放的是静态常量,和字符串常量。在类一开始被加载的时候此常量就被初始化放在这个区内,而且被全局所共享,所有的访问直接指向他即可。
4:code segment,代码区,它是存放代码的区,所有的执行代码(其实就是函数)都放在此区内。通过对象的调用指向此区。
现假设两个线程正企图同时访问一个单例对象的方法,如
int method1(int i) {
int j = 3;
return i+j;
}
一个规范的虚拟机线程在调用method1()的时候是这样做的:
1) 把method1()的局部变量,包括参数,压入当前线程的栈;
2) 从当前线程栈弹出变量j,并赋予数值3;
3) 从当前线程栈弹出参数i,与j执行加法运算;
4) 从当前线程栈中释放当前方法占用的栈帧,并把method1()的结果压入当前线程栈。
需要说明的是,当前线程栈是当前线程独有的,绝对不会被其它线程访问到。