【问题标题】:Does static has special meaning in Java Threads?静态在 Java 线程中是否有特殊含义?
【发布时间】: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();
        } 
    }
}

它无法通过测试用例。但是当我将 firstFinishedsecondFinished 更改为非静态时,它通过了所有测试用例。我不知道它发生了什么事。我在为它们分配 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


【解决方案1】:

first runnable class 中尽量避免.notifyall 例如:

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

           // if class notify then only it has to give descending order, try it this way.

【讨论】:

  • 感谢您的回答。我认为JBNizet已经解释得很好,问题是没有调用notifyAll。
猜你喜欢
  • 2013-04-18
  • 2012-12-21
  • 1970-01-01
  • 2015-09-08
  • 2019-08-03
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
相关资源
最近更新 更多