11

静的メソッド内の変数について質問があります。静的メソッド内の変数は同じメモリ位置を共有していますか、それとも別のメモリを持っていますか?

ここに例があります。

public class XYZ
{
    Public Static int A(int value)
    {
      int b = value;
      return b;
    }
}

3 つの異なるユーザー呼び出しがメソッド A を実行する場合

XYZ.A(10);
XYZ.A(20);
XYZ.A(30);

同時に。各呼び出しの戻り値は何でしょうか?

XYZ.A(10)=?
XYZ.A(20)=?
XYZ.A(30)=?
4

4 に答える 4

17

それらは依然としてローカル変数であり、スレッド間で共有されません。それらが静的メソッド内にあるという事実は、違いはありません。

静的変数を中間変数として使用した場合、それ安全ではありません。

public class XYZ
{
    // Don't do this! Horribly unsafe!
    private static int b;
    public static int A(int value)
    {
        b = value;
        return b;
    }
}

ここでは、すべてのスレッドが実際に同じb変数を使用しているため、複数のスレッドからメソッドを同時に呼び出すと、スレッド X が に書き込みb、続いてスレッド Y に書き込み、スレッド X がスレッド Y によって設定された値を返すことになります。

于 2010-08-03T19:10:46.110 に答える
4

変数は完全にスタック上にあるため、スレッドは互いの値を上書きしません。各スレッドには個別のスタックがあります。

于 2010-08-03T19:10:38.547 に答える
1

これはスレッドセーフな方法ではありませんが、関数が呼び出されるたびに新しいスタックフレームを取得するため、すべての自動変数は自動的にスレッドセーフになります。すべてのローカルは、関数へのエントリ時に作成され、終了時に破棄されます。上で述べたように、静的ストレージを使用していた場合、予期しない結果が得られます。

于 2010-08-03T19:15:07.893 に答える
1

いいえ、それらはメモリ内の同じスペースを共有しません。あなたの呼び出しに対して、彼らは(リストした順序で)、、、およびを10返し20ます30

正直なところ、あなたのコードでは、これはいずれの場合にも当てはまります (値を代入しているだけで、何もしていないため) が、次のことを考慮してください。

Class XYZ
{
   public static int A (int value)
   {
      b += value;  \\Won't compile: b not initialized
      return b;
   }
}

または

Class XYZ
{
   public static int A (int value)
   {
      int b = 0;  \\Initialized 'b' for each call
      b += value;  
      return b;
   }
}

静的メソッドはインスタンス変数にアクセスできないため (少なくとも、インスタンスへの参照がないわけではありません)、コードが呼び出されるたびに変数を再初期化せずに静的メソッドで一度変数を初期化する方法はありません。静的メソッドが変数を変更できるようにするには、2 つの値を渡して相互に操作する必要があります。

于 2010-08-03T19:15:28.613 に答える