【问题标题】:Concurrent static context并发静态上下文
【发布时间】:2018-08-24 11:56:36
【问题描述】:

我想了解静态上下文在多线程环境中的工作原理。 如果你在一个类中有一个静态方法,可以说“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*/ 

函数的内部状态会发生什么?还有,接收到的参数值会怎样?

每个值会是一个不同的值,还是它们共享相同的内存?

根据我的理解,静态变量不在堆栈中,而是在堆中,所以它们应该共享它们,因此代码不会是线程安全的,对吗?

【问题讨论】:

    标签: java multithreading concurrency static


    【解决方案1】:

    局部变量是孤立的。这包括方法参数。每个线程都有自己的堆栈,与该线程中的方法调用相关的局部变量存储在该线程的堆栈内存中。

    因此,对于方法notSafeStaticMethod,无论两个调用的相对时间如何,这两个线程都不会看到对方的(局部变量)值或无法操作它们。

    只需要注意共享变量(例如,如果localString 在类中声明为静态字段,或作为方法参数传递的共享变量),除非正确同步,否则线程可以覆盖彼此的更改。

    【讨论】:

    • 我有点困惑,我记得当我使用 restFul bean 时,它们应该由每个线程的上下文实例化。由于它们是 restFul,因此使用包含公共代码的静态类会更有效。那我就不明白为什么要用restful beans了。
    • @DavidMarciel 我假设您指的是静态方法。这没有问题。这是一种方法,而不是状态。换句话说,两个线程没有机会干扰彼此的执行或数据。
    【解决方案2】:

    在静态方法中声明的变量不是静态变量,它们是局部变量,它们位于该线程的堆栈中(尽管引用变量指向堆上的位置),位于专用于特定方法调用的堆栈帧中.所以没有其他线程干预的机会,每个方法调用都是隔离的。

    现在,如果静态方法使用了静态变量,则可以同时访问这些变量。静态变量在类中使用关键字 static 声明。因此,请确保您可以识别静态变量。

    顺便说一句,嵌套类可以标记为静态,这意味着只有该类的对象没有对它们被声明为嵌套在其中的类的对象的引用(参见 java.util.Map.以条目为例)。 static 在这种情况下并不意味着类中的变量或方法是静态的。这只是 Java 实现者重用现有关键字,因此他们不会冒险破坏预先存在的代码。

    public class Example {
    
        static int staticVariableHere;
    
        public static int staticMethodHere(String methodArg) {
            int localVariable = 42;
            return localVariable;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-10
      • 1970-01-01
      相关资源
      最近更新 更多