在java中static用來修飾Class類中屬性和方法。
被static修飾的成員屬性和成員方法獨立於該類的任何對象,它們在內存空間上會被放在描述Class的位置中,也就是說它們為此類(Class)所有的實例對象共用。
所以說只要這個類被加載,那么這些被static修飾的屬性和方法都已經在JVM中存在了,因此,我們可以通過類名直接調用這些屬性和方法。
那么我就想到了一個在多線程和並發的情況下,被static修飾的方法會不會出現不正確的數據處理呢?
下面寫一段測試的代碼
Porter.java
public class Porter {
public static void test(int num){
System.out.printf("time : %s , num : %d \n",System.currentTimeMillis(),num);
}
}
Runner.java
public class Runner implements Runnable{
private int num;
@Override
public void run() {
Porter.test(getNum());
}
public void setNum(int num){
this.num = num;
}
public int getNum(){
return this.num;
}
public static void main(String args[]){
Thread th[] = new Thread[100];
for (int i = 0; i < th.length; i++) {
Runner run =new Runner();
run.setNum(i);
th[i] = new Thread(run);
th[i].start();
}
}
}
在這個多線程程序中,run()方法一直都在調用Porter的一個static方法test()。實際程序輸出如下:
time : 1423399741495 , num : 0
time : 1423399741521 , num : 40
time : 1423399741520 , num : 39
time : 1423399741520 , num : 38
time : 1423399741518 , num : 37
time : 1423399741518 , num : 36
time : 1423399741517 , num : 34
time : 1423399741517 , num : 35
time : 1423399741523 , num : 43
time : 1423399741516 , num : 32
time : 1423399741516 , num : 33
time : 1423399741516 , num : 30
time : 1423399741516 , num : 31
time : 1423399741515 , num : 29
time : 1423399741515 , num : 28
……
雖然省略了一部分,但是程序確實沒有執行錯誤,通過系統的時間戳發現,中間有幾個線程確實也是同時執行的。這樣說來被static修飾的方法並不存在並發的問題,那么這是為什么呢?
其實這就是變量的問題了,每次靜態方法每次調用的內部變量,都是局部變量,每次調用靜態方法時都會為它重新分配內存空間,所以是安全的。