2010-08-03 418 views
10

我對靜態方法內部的變量有疑問。 靜態方法中的變量是否共享相同的內存位置,或者它們是否具有單獨的內存?靜態方法內部變量共享

這裏是一個例子。

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

如果3個不同的用戶的呼叫的同時執行該方法的

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

。每個電話的返回值是什麼?

XYZ.A(10)=? 
XYZ.A(20)=? 
XYZ.A(30)=? 
+0

請參閱:http://stackoverflow.com/questions/420895/how-do-i-know-if-a-c-method-is-thread-safe – 2010-08-03 19:12:19

+0

你使用任何線程? – 2010-08-03 20:18:53

回答

15

它們仍然是局部變量 - 它們不在線程之間共享。它們處於靜態方法的事實沒有任何區別。

如果您使用的靜態變量作爲中間變量,是不安全的:

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設置的值。

4

線程不會覆蓋對方的值,因爲變量完全在堆棧上。每個線程都有一個單獨的堆棧。

1

這不是線程安全的方法,但所有自動變量是自動線程安全的,因爲每次調用該函數都會得到一個新的棧幀。所有當地人在進入該功能時創建並在退出時被銷燬。如上所述,如果您使用過靜態存儲,那麼您會得到意想不到的結果。

1

不,它們在內存中不共享相同的空間。對於您的電話,他們將返回(按列出的順序):10,2030

說實話,你的代碼,這將在任何情況下是正確的(因爲你只是分配一個值,沒有做任何事的),但考慮:

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; 
    } 
} 

由於靜態方法不能訪問實例變量(至少不是沒有對實例的引用),所以沒有辦法在靜態方法中初始化一個變量,而不必在每次調用代碼時重新初始化變量。爲了允許靜態方法更改變量,您需要傳入兩個值以相互操作。

+0

除非你有一個靜態變量,當然。 – 2010-08-03 19:30:16

+0

是的。但是,很少使用它們,我忘了它們......對於這個特定的問題,這看起來並不是一個問題。 – AllenG 2010-08-03 19:43:14