【发布时间】:2019-12-26 16:14:56
【问题描述】:
最近,我在 Leetcode 中锻炼时遇到了一个奇怪的问题 问题是Print in Order。下面是我的解决方案
class Foo {
private static boolean firstFinished=false;
private static boolean secondFinished=false;
private static final Object lock = new Object();
public Foo() {
}
public void first(Runnable printFirst) throws InterruptedException {
synchronized (lock) {
// printFirst.run() outputs "first". Do not change or remove this line.
System.out.print("first");
System.out.println(firstFinished);
printFirst.run();
firstFinished = true;
lock.notifyAll();
}
}
public void second(Runnable printSecond) throws InterruptedException {
synchronized (lock) {
while (!firstFinished) {
lock.wait();
}
System.out.print("second");
System.out.println(secondFinished);
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
secondFinished = true;
lock.notifyAll();
}
}
public void third(Runnable printThird) throws InterruptedException {
synchronized (lock) {
while (!secondFinished) {
lock.wait();
}
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
}
}
}
它无法通过测试用例。但是当我将 firstFinished 和 secondFinished 更改为非静态时,它通过了所有测试用例。我不知道它发生了什么事。我在为它们分配 True 值之前打印了 firstFinished 和 secondFinished 的值,在我分配给它们之前它们似乎变成了真实的。谁能告诉我发生了什么?静态在 Java 线程中是否有特殊含义?
【问题讨论】:
-
"static在Java中有特殊含义吗?" - 有含义,否则有关键字就没意义了,不是吗?它的语义是静态方法或字段绑定到类本身,而不是它的实例。这意味着如果某个东西是
static,它会在类的所有实例之间共享。 -
阅读docs.oracle.com/javase/tutorial/java/javaOO/classvars.html。读完之后,想一想 Leetcode 会创建多个 Foo 类的实例。多次执行测试。第二次测试会发生什么?
-
@JBNizet 在问题描述中,他说“Foo 的同一个实例将被传递给三个不同的线程。”但它不应该在我分配给它们之前更改静态变量值。我是对MultiThreads不是很熟悉,能详细解释一下吗?
-
一个测试将使用 Foo 的一个实例并将其传递给 3 个线程。但这并不意味着 Leetcode(或者更实际的应用程序)不会重复这样做,即有一个循环来创建 Foo,将其传递给三个线程,并每次都验证结果是否正确。你读过我链接的页面吗?我问你的问题你会怎么回答?
-
@GhostCatsaysReinstateMonica 我在Java线程中搜索了一些关于静态含义的东西,但我得到的结果是静态意味着它绑定到类而不是对象,但它仍然无法解决我的问题,在多线程中,当你使用静态时,你无法通过测试,但当你使用非静态时它通过了。我不认为原因是静态绑定到类而不是对象
标签: java multithreading thread-safety