static关键字

来源:互联网 发布:看淘宝 编辑:程序博客网 时间:2024/06/16 22:09

Static关键字

在使用类的方法和变量时,一般需要用new来创建类的对象,类的数据存储空间才会被分配,方法才能被使用。

有两种情况通过new对象无法解决。一:类的变量不想和对象关联在一起,对象不存在时变量可以分配单一空间(类加载时分配)。这样对象可以共同使用这个变量,所有对象的这个属性值都是一样的,只开辟一个空间进行存储。二:类的方法想可以直接调用,不需要通过new对象来用。

static变量和方法可以解决以上两个问题。它们俩都是通过类关联的,所以可以叫做类变量和类方法。

ps:还有一个叫静态代码块,在类加载的时候执行,和new对象无关,只执行一次,用处就是想在类加载的时候就预先执行一些操作。

Static变量和方法的线程安全问题

Static变量是线程非安全的,因为类的所有对象都可以修改它,可能会同时修改它。Static方法线程安不安全要看静态方法里是否存在“全局”或“共享”变量。

下面代码静态方法不存在“全局”或“共享”变量,所以是线程安全的。

public class StaticThread1 implements Runnable {    @Override    public void run() {        // TODO Auto-generated method stub        StaticAction1.print();    }    public static void main(String[] args) {        for (int i = 0; i < 100; i++) {            new Thread(new StaticThread1()).start();        }    }}class StaticAction1 {    public static int i = 0;    public static void print() {        int sum = 0;        for (int i = 0; i < 10; i++) {            System.out.print("step " + i + " is running.");            sum += i;        }        if (sum != 45) {            System.out.println("Thread error!");            System.exit(0);        }        System.out.println("sum is " + sum);    }}

下面代码静态方法不存在“全局”或“共享”变量,所以是线程不安全的。需要加上在incValue()方法上加上synchronized关键字。

public class StaticThread2 implements Runnable {    @Override    public void run() {        // TODO Auto-generated method stub        StaticAction.incValue();    }    public static void main(String[] args) {        for (int i = 0; i < 100; i++) {            new Thread(new StaticThread2()).start();        }        try {            Thread.sleep(1000); // 预留足够的时间让上面的线程跑完        } catch (Exception e) {            e.printStackTrace();        }        System.out.println(StaticAction.i);    }}class StaticAction {    public static int i = 0;    public static void incValue() {        int temp = StaticAction.i;        try {            Thread.sleep(1);        } catch (Exception e) {            e.printStackTrace();        }        temp++;        StaticAction.i = temp;    }}
0 0