Javaでの静的フィールドの初期化

エニスヤン:

LeetCodeに質問をしているとき、私はこの問題が発生しました:https://leetcode.com/problems/print-in-order/

2つの提出を考えてみます。

1。

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();
    }
}

2。

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();
    }
}

これら二つを提出してみて、あなたが提出1になります見つける超過時間制限提出2が受け入れられますながら。

唯一の違いは、提出2に、私は明示的に文の追加ということであるsignal = 0;静的変数を初期化するが。私はすでにこの変数にではデフォルト値を与えているように、それは何の違いを再生するべきではありませんprivate static int signal = 0;ので、ここで何が起こっていますか。私が知らなかったことをJavaで静的フィールドの初期化のいずれかの微妙な点はありますか?

どうもありがとうございました。

ウィリスブラックバーン:

LeetCodeは、ソリューションに対するいくつかの異なるテストケースを実行します。さんはLeetCodeは、単一のJVMを実行し、そのJVM内のすべてのテストケースを実行しているが、それは新しいをインスタンス化されていると仮定しましょうFoo各ケースのために。

最初のケースを実行している場合は、signalゼロであり、期待どおりのコードは動作します。しかし、このテストケースの終わりにsignalテストケースが二回、それをインクリメントするので、今2です。それは静的なので、それはすべてのインスタンス間で共有されますFooLeetCode新しいインスタンスにもかかわらず、Foo第二のテストケースのために、静的はsignal依然として2であるfirst方法増分それ3に、その後の試験ハング条件があるためwhile (signal != 1)、常に真です。

初期化signalで0にFooコンストラクタはリセットの影響有するsignal第二およびその後のテスト実行の前に。

作成する理由はありませんsignalここで静的。各インスタンスは、そのように、それは、通常の非静的メンバである必要がありFoo、新規に取得signalゼロに初期化。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=363577&siteId=1