我想了解静态上下文如何在多线程环境中工作。 如果您在类中具有静态方法,请说“ ContainerClass.notSafeStaticMethod();”。您可以同时从不同的线程调用它。
方法内部的变量是否共享?
public class ContainerClass{
public static String notSafeStaticMethod(String stringParameter) {
String localString = stringParameter + "1";
localString += "2";
localString += "3";
return localString;
}
}
然后两个线程同时调用它:
ContainerClass.notSafeStaticMethod( "first Call"); /*Thread 1 is executing*/
ContainerClass.notSafeStaticMethod( "Second Call"); /*Thread 2 starts executing before thread 1 finishes*/
函数的内部状态会发生什么?还有,接收到的参数值会发生什么?
每个值将是一个不同的值,还是它们共享相同的内存?
根据我的理解,静态变量不在堆栈中,而是在堆中,因此它们应该共享它们,因此代码不是线程安全的,对吗?
答案 0 :(得分:3)
局部变量是隔离的。这包括方法参数。每个线程都有自己的堆栈,并且与该线程中的方法调用相关的局部变量存储在该线程的堆栈内存中。
因此,对于方法notSafeStaticMethod
,无论两个调用的相对时间如何,两个线程都不会看到另一个(局部变量)的值或能够操纵它们。
仅对于共享变量才需要维护(例如,如果在类中将localString
声明为静态字段,或者将共享变量作为方法参数传递),在这种情况下线程可以覆盖彼此的更改,除非完成正确的同步
答案 1 :(得分:2)
在静态方法内部声明的变量不是静态变量,它们是局部变量,并且在该线程的堆栈中(尽管参考变量指向堆中的位置),在专用于特定方法调用的堆栈框架中。因此,其他线程没有机会进行干预,每个方法调用都是隔离的。
现在,如果静态方法使用了静态变量,则可以同时访问这些变量。静态变量在类中使用关键字static声明。因此,请确保您可以识别静态变量。
顺便说一句,嵌套类可以标记为静态,这意味着仅该类的对象没有对它们声明为嵌套在其中的类的对象的引用(请参见java.util.Map。输入示例)。 static
在此上下文中并不意味着该类中的变量或方法是静态的。只是Java实现者重用了现有的关键字,因此他们不必冒破坏已有代码的风险。
public class Example {
static int staticVariableHere;
public static int staticMethodHere(String methodArg) {
int localVariable = 42;
return localVariable;
}
}