Java中的静态字段初始化

Java中的静态字段初始化,java,Java,我在回答LeetCode问题时遇到了这个问题: 考虑两份意见书: 一, 二, 尝试提交这两个,您会发现提交1将导致超过时间限制,而提交2将被接受 唯一的区别是,在提交2中,我明确添加了一条语句signal=0初始化静态变量。它应该没有区别,因为我已经在private static int signal=0中给了这个变量一个默认值,那么这里发生了什么。Java中静态字段初始化是否有我不知道的微妙之处 非常感谢。LeetCode针对您的解决方案运行多个不同的测试用例。让我们假设LeetCode运行一

我在回答LeetCode问题时遇到了这个问题:

考虑两份意见书:

一,

二,

尝试提交这两个,您会发现提交1将导致超过时间限制,而提交2将被接受

唯一的区别是,在提交2中,我明确添加了一条语句
signal=0
初始化静态变量。它应该没有区别,因为我已经在
private static int signal=0中给了这个变量一个默认值,那么这里发生了什么。Java中静态字段初始化是否有我不知道的微妙之处


非常感谢。

LeetCode针对您的解决方案运行多个不同的测试用例。让我们假设LeetCode运行一个JVM并在该JVM中运行所有测试用例,但它为每个用例实例化一个新的
Foo

当运行第一种情况时,
信号
为零,代码按预期工作。但是在这个测试用例的末尾,
信号现在是2,因为测试用例将它增加了两倍。因为它是静态的,所以它在
Foo
的所有实例之间共享。即使LeetCode为第二个测试用例实例化了一个新的
Foo
,静态
信号仍然是2。
first
方法将其递增为3,但随后测试将挂起,因为条件
while(signal!=1)
始终为真

Foo
构造函数中将
signal
初始化为0会在第二次和后续测试运行之前重置
signal


没有理由在这里设置
信号
静态。它应该是一个常规的非静态成员,这样
Foo
的每个实例都会得到一个初始化为零的新
信号。

为什么选择将字段设置为静态?静态场和非静态场有什么区别?如果创建两个Foo实例,会发生什么?提交这两个实例是什么意思?超过了时间限制,什么时候被接受?谢谢。。。糟糕的是,我没有注意到“同一个Foo实例将被传递给三个不同的线程”。我以为每个线程都会有一个不同的实例。如果每个线程都有一个单独的
Foo
,那么即使有一个静态
信号
,您的解决方案也不会工作,因为您的方法不是静态的,因此在类实例上同步。给定实例
foo1
foo2
foo1完全可以。首先
foo2同时运行。其次
,因为它们是不同的实例。@Slaw这就是他试图实现的,在三个
Foo
实例之间共享
信号。
class Foo {
    private static int signal = 0;
    public Foo() {}

    public synchronized void first(Runnable printFirst) throws InterruptedException {
        // printFirst.run() outputs "first". Do not change or remove this line.
        printFirst.run();
        signal += 1;
        notifyAll();
    }

    public synchronized void second(Runnable printSecond) throws InterruptedException {
        while(signal != 1)
            wait();

        // printSecond.run() outputs "second". Do not change or remove this line.
        printSecond.run();
        signal += 1;
        notifyAll();
    }

    public synchronized void third(Runnable printThird) throws InterruptedException {
        while(signal != 2)
            wait();

        // printThird.run() outputs "third". Do not change or remove this line.
        printThird.run();
        notifyAll();
    }
}
class Foo {
    private static int signal = 0;
    public Foo() {signal = 0;}

    public synchronized void first(Runnable printFirst) throws InterruptedException {
        // printFirst.run() outputs "first". Do not change or remove this line.
        printFirst.run();
        signal += 1;
        notifyAll();
    }

    public synchronized void second(Runnable printSecond) throws InterruptedException {
        while(signal != 1)
            wait();

        // printSecond.run() outputs "second". Do not change or remove this line.
        printSecond.run();
        signal += 1;
        notifyAll();
    }

    public synchronized void third(Runnable printThird) throws InterruptedException {
        while(signal != 2)
            wait();

        // printThird.run() outputs "third". Do not change or remove this line.
        printThird.run();
        notifyAll();
    }
}