5

您可以在下面看到counterJava 类中的静态变量。

问题是这个变量什么时候会重置?例如,当我重新启动程序时,计算机。它可以重置的其他可能情况是什么?

另一个问题是:这个变量增加的次数少于函数 do() 执行次数的原因是什么?例如,是否可以启动类的多个进程java Whatever?或者它可能是具有多个线程/服务器等的东西?

class Whatever {

    static int counter = 0;

    function do() {
        counter++;
        //...
    }

}

附加问题:如果多个线程执行函数do(),计数器变量将如何表现?它会少于函数 do() 执行的次数吗?

4

7 回答 7

2

根据JLS

如果一个字段被声明为静态的,那么无论最终创建多少个类的实例(可能为零),都只存在该字段的一个化身。静态字段,有时称为类变量,在类初始化时体现

所以这回答了你的第一个问题。iee 正是在加载类时:)

根据第二个问题,不。如果变量被声明为私有的。然后由于封装,唯一的访问是通过方法。

静态变量一直持续到 JVM 关闭。

于 2012-11-22T11:09:13.120 回答
2

重新启动应用程序时将重新初始化静态变量。

于 2012-11-22T11:09:09.633 回答
1

counter is not a private variable. So it is possible that this value is changed by some other class.

This variable will get reset whenever your program (or specifically the container/jvm) is restated.

于 2012-11-22T11:10:46.647 回答
0

1) The variable is set(reset) when the class is loaded. Apart from shutting down the JVM, some servers load the class in different applications (v.g., the Tomcat webapps) and some of them allow restarting them.

2) Concurrent modification by threads. But it should be rare, unless you use it a lot. Use synchronized for the function/block.

于 2012-11-22T11:10:35.250 回答
0

The question is when will this variable reset?

static variable can be reset using custom reset() method. If You say restart program, theoretically that variable will be initialized to it's value not reinitialized as it is not same(you restart program).

于 2012-11-22T11:13:48.267 回答
0

静态变量意味着在程序执行期间该字段只有一个化身。它在类初始化时加载。

对于第二个问题,您的变量不是线程安全的,因为多个线程可以同时访问它。即使您的计数器不稳定,您仍然会面临并发问题。根据您的示例和要求,您有三个选项:

如果您唯一的要求是操纵变量并且其余代码不依赖于此,您可以使用同步(用大炮杀死苍蝇)或AtomicInteger(性能更好的选择):

static synchronize int counter = 0;
// or
static AtomicInteger counter = new AtomicInteger();

如果您的其余代码依赖于您的计数器,则必须使用锁定对象或同步您的方法:

class Whatever {

    static int counter = 0;

    synchronize function do() {
        counter++;
        if(counter < 10){
            //  do something
        }
    }
}

//  or

class Whatever {

    static int counter = 0;
    static final Object _lock = new Object();

    function do() {
        synchronized (_lock) {
            counter++;
            if(counter < 10){
                //  do something
            }
        }
    }
}

这是我现在脑海中的选项,但可能还有更多。

于 2012-11-22T12:05:02.923 回答
0
class Foo { // in same package
public static void main(String[] args) {
    Whatever w = new Whatever();
    for (int i = 0; i < 1000; i++) {
        w.do();
    }
    Whatever.counter = -1;
}

这里do()被调用了 1000 次,但counter最后会有值。

do()在您的示例中像您一样使用过,但请注意这不是有效的方法名称,因为它是 do while 循环的关键字。

于 2012-11-22T11:15:10.227 回答