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