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です。それは静的なので、それはすべてのインスタンス間で共有されますFoo
。LeetCode新しいインスタンスにもかかわらず、Foo
第二のテストケースのために、静的はsignal
依然として2であるfirst
方法増分それ3に、その後の試験ハング条件があるためwhile (signal != 1)
、常に真です。
初期化signal
で0にFoo
コンストラクタはリセットの影響有するsignal
第二およびその後のテスト実行の前に。
作成する理由はありませんsignal
ここで静的。各インスタンスは、そのように、それは、通常の非静的メンバである必要がありFoo
、新規に取得signal
ゼロに初期化。