简短的回答是肯定的,以下方法是线程安全的:
public static int CalcuateSomething( int number ) {
int i = number * 10;
return i;
}
只要不指向堆上的共享对象,所有局部变量都是安全的。
就像您在单线程应用程序的情况下一样,此方法的以下调用将返回不同的值。
CalculateSomething( 10 ) => 100
CalculateSomething( 20 ) => 200
这是为什么呢?因为方法编号的每次调用都采用不同的值,因此我也会这样做。函数结束后不会记住 i 的值,因为 i 是在堆栈上分配的。在几乎所有语言中,函数都是堆栈模型。每次调用不同的方法时,当前方法都会暂停。一个新方法被压入调用堆栈并被调用。当该方法完成时,程序取消暂停调用方法并从它停止的地方恢复(即在 returnAddress 处)。在该方法中定义的任何局部变量都是该方法的堆栈帧的一部分。我们上面方法的堆栈帧可以这样想:
public Class StackFrameForCalculateSomething implements StackFrame {
public int ReturnAddress;
public int i = 0;
public int number;
}
堆栈可以被认为是 StackFrame 对象的集合。
堆栈调用堆栈
每次调用新方法时,程序可能会执行以下操作:
StackFrameForCalculcateSomething s = new StackFrameForCalculateSomething();
s.returnAddress = instructionPointer;
s.number = 10;
callStack.push( s );
s.invoke();
StackFrameForCalculcateSomething s2 = new StackFrameForCalculateSomething();
s2.returnAddress = instructionPointer;
s2.number = 20;
callStack.push( s2 );
s2.invoke();
这对线程意味着什么?好吧,在线程的情况下,您将拥有多个具有自己集合的独立 callStack。访问局部变量是安全的原因是线程 1 的 callStack 无法访问线程 2 的 callStack,因为它们是单独的对象。就像在单线程情况下 s 和 s2 是具有不同数字值的不同对象。因此它们彼此独立。考虑 s 在线程 1 中,而 s2 在线程 2 中。线程 1 和线程 2 不共享任何内存,因此它是线程安全的。
线程不共享它们的堆栈帧。他们确实共享堆。