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的继承问题
- 父类中的静态方法可以被子类的静态方法覆盖,但没有多态的性质
- 类的加载,类只有在创建对象的时候才会加载类,调用类中的静态方法或静态属性也是会加载类的。加载子类时必先加载父类。