Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java'synchronized'块是否锁定对象引用或值?_Java_Multithreading_Synchronization_Synchronized_Synchronized Block - Fatal编程技术网

Java'synchronized'块是否锁定对象引用或值?

Java'synchronized'块是否锁定对象引用或值?,java,multithreading,synchronization,synchronized,synchronized-block,Java,Multithreading,Synchronization,Synchronized,Synchronized Block,给出如下所示的输出: 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.toStrin

给出如下所示的输出:

    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
    }


如(JLS)中所述,
synchronized
语句锁定对象。如果您认为“value”是字符串值(如
path1.toString().equals(path2.toString())
),那么答案是“no”-您的代码几乎肯定不是线程安全的。按照JLS的说法,如果表达式的类型是引用类型(如
synchronized
语句所需),则该表达式的值要么是
null
要么是对象。除非两个
toString()
调用返回相同的对象引用(
path1.toString()==path2.toString()
)。

如(JLS)中所述,
synchronized
语句锁定对象。如果您认为“value”是字符串值(如
path1.toString().equals(path2.toString())
),那么答案是“no”-您的代码几乎肯定不是线程安全的。按照JLS的说法,如果表达式的类型是引用类型(如
synchronized
语句所需),则该表达式的值要么是
null
要么是对象。除非两个
toString()
调用返回相同的对象引用(
path1.toString()==path2.toString()
),否则所发布代码中的两个块不是互斥的。

引用就是值。这是一个没有区别的区别
toString()
是一个参考。它不会与任何其他
toString()
值相同,除非它们都已被插入,或者它们都来自相同或相同的字符串文本。

引用就是该值。这是一个没有区别的区别
toString()
是一个参考。它不会与任何其他
toString()
值相同,除非它们都已被插入,或者它们都来自相同或相同的字符串文本。

每个对象都有自己的监视器;这就是同步块获取的内容。因此,只有当
path1.toString()==path2.toString()
时才会出现互斥。通常,在方法调用的结果上进行同步不是一个好主意:即使在两个线程中仅在
path1.toString()
上进行同步,如果总是返回一个新对象,可能根本不会得到互斥(你不知道情况是否如此,可能会随意改变)。你当然不能指望这些引用是相同的。很可能它们不会相同。无论如何,你为什么要锁定一个
字符串
字符串
携带了大量的运费和语义,仅用作锁定对象。你只需要一个
对象
。每个对象都有自己的监视器;这是由同步块。因此,只有当
path1.toString()==path2.toString()
时才会出现互斥。通常,根据方法调用的结果进行同步不是一个好主意:即使您只是在
path1.toString()上进行同步
在两个线程中,如果总是返回一个新对象,则可能根本不会得到互斥(您不知道是否是这种情况,并且它可能会任意更改)。你当然不能指望这些引用是相同的。很可能它们不会相同。无论如何,你为什么要锁定
字符串
字符串
携带了大量的运费和语义,仅用作锁定对象。你只需要一个
对象
。我想OP想知道两个测试相等的字符串是否相同(使用
equals()
)就足以确保线程安全。@TedHopp我看不出猜测他的意思有任何意义。我正在回答他问的问题。是的,Ted,我想知道在
同步()中判断两个对象相等时是否使用
equals()
=
关键字。@albusshin那么你应该在你的问题中这样说。一旦你真的写下来,你就会发现它没有意义。为什么
synchronized
会比较对象?@albusshin没有“thing”。它是一个方法。它比较它喜欢的任何东西,或者什么都没有,并返回一个值。我想OP想知道two测试为相等的字符串(使用
equals()
)就足以确保线程安全。@TedHopp我认为猜测他可能是什么意思或可能不是什么意思没有任何意义。我正在回答他问的问题。是的,Ted,我想知道
equals()
==
用于判断
同步()
关键字。@albusshin那么你应该在你的问题中这样说。一旦你真的写下来,你就会发现它没有意义。为什么
同步的
会比较对象?@albusshin没有“东西”。它是一个方法。它比较它喜欢的任何东西,或者什么都没有,并返回一个值。这与我们不喜欢的相反他引用引用的引用告诉我们。它说,“否则,让表达式的非空值为V。执行线程锁定与V关联的监视器。”它锁定与表达式关联的监视器,而不是像这个答案所说的那样锁定引用上的监视器。此外,正如§17.1所述,监视器与对象关联,而不是引用。Java中的每个对象都与一个监视器相关联,线程可以锁定或解锁该监视器。"@LewBloch再次强调,这是一个没有区别的区别。这是一个引用值表达式。说JLS的相反词确实会产生区别,特别是当它解决OP提出的确切问题并给出相反的答案时。不仅如此,你只需阅读几分钟就可以看到混乱造成的损失有多大