1.static 準則
- 靜態方法中不能引用非靜態方法或變量,這是static的主要用途。
public class FatherA {
public static int a=100;
//public static int b=200;
public int d=300;
public static void printa() {
System.out.println(a);
}
public void printd() {
System.out.print(d);
}
public static void printb() {
System.out.println(d); // ERORRRRRRRR!!!!
}
- 多線程調用靜態方法,只要靜態方法中不涉及全局變量,即靜態變量,那麼這兩個線程不會相互影響(但大多數時候需要調用靜態變量)
public class FatherA {
public static int a=100;
//靜態方法中不涉及靜態變量
public static void printThread() {
int sum=0;
for(int i=0;i<100;i++) {
sum+=i;
}
System.out.println(sum);
}
//靜態方法中涉靜態變量
public static void printThreadD() {
for(int i=0;i<100;i++) {
FatherA.a+=i;
}
System.out.println(FatherA.a);
}
}
public class MultiThread implements Runnable{
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
// TODO Auto-generated method stub
FatherA.printThread();
//FatherA.printThreadD();
}
}
public class Main {
public static void main(String[] args) {
MultiThread t1=new MultiThread();
MultiThread t2=new MultiThread();
new Thread(t1).start();
new Thread(t2).start();
}
}
運行結果:
4950
4950
然後調用FatherA.printThreadD()方法
10000
10000
9512
9512
7825
7825
可以看到每次輸出的結果都是隨機的,也就產生了影響,兩個線程操作的都是全局字段。
此時在靜態方法上加上關鍵字synchronized。該方法叫做同步靜態方法,線程監視器會獲取類本身的對象鎖,其他線程不能進入這個類的任何靜態同步方法。
運行結果:
5050
10000
分析:未加入控制字段的訪問靜態方法明顯是不可取的,會對邏輯結構產生影響。而加入了控制字段的靜態方法在多線程方面表現的像一個順序執行的任務,都在等待臨界資源佔用的釋放。
static的繼承問題
- 父類中的靜態方法可以被子類的靜態方法覆蓋,但沒有多態的性質
- 類的加載,類只有在創建對象的時候纔會加載類,調用類中的靜態方法或靜態屬性也是會加載類的。加載子類時必先加載父類。