2

给定如下所示的输出:

    Path path1 = Paths.get("/Users/someone/foo");
    Path path2 = Paths.get("/Users/someone/foo");
    System.out.println(path1.toString() == path2.toString()); // outputs false
    System.out.println(path1.toString().equals(path2.toString())); // outputs true

给定以下两个线程,两个线程是否有可能同时在临界区运行?

    // Thread 1
    synchronized (path1.toString()) {
        // Critical section
    }

    // Thread 2
    synchronized (path2.toString()) {
        // Critical section
    }
4

2 回答 2

7

参考就是价值。这是没有区别的区别。toString()是参考。它不会与任何其他toString()值相同,除非两者都已被实习,或者它们都源自相同或相同的字符串文字。

于 2017-03-05T22:00:13.383 回答
4

正如Java 语言规范第 14.19 节(JLS) 中所述,synchronized语句锁定对象。如果您将“值”视为字符串值(如 中path1.toString().equals(path2.toString())),那么答案是“否”——您的代码几乎肯定不是线程安全的。用 JLS 的说法,如果表达式的类型是引用类型(根据synchronized语句的要求),那么该表达式的就是null对象或对象。您发布的代码中的两个块不是互斥的,除非两个toString()调用返回相同的对象引用 ( path1.toString() == path2.toString())。

于 2017-03-05T21:57:12.630 回答