Java:如果同步发生更改,它不会阻塞
相关的 输出:Java:如果同步发生更改,它不会阻塞,java,multithreading,Java,Multithreading,相关的 输出: from first block start 0 from second block start from second block done 1 1 from first block done 在相关答案中,它们都保持原始参考,因此第二个块应被阻止,直到第一个块完成 然而,第二个块确实进行了一次a.lockObj更改了第一个块。为什么?您正在创建两个对象,因此让我们命名它们以供参考: 在字段初始值设定项中创建ObjA 在sleep(1000) 线程中的synchroniz
from first block start
0
from second block start
from second block done
1
1
from first block done
在相关答案中,它们都保持原始参考,因此第二个块应被阻止,直到第一个块完成
然而,第二个块确实进行了一次
a.lockObj
更改了第一个块。为什么?您正在创建两个对象,因此让我们命名它们以供参考:
- 在字段初始值设定项中创建ObjA
- 在sleep(1000)
synchronized(a.lockObj)
块锁定在ObjA上
由于启动线程后您有sleep(100)
,因此当主线程到达其synchronized(a.lockObj)
块时,线程将更改a.lockObj
以引用ObjB,从而将锁定到不同的对象上
作为不同的对象,代码不会阻塞
提示:锁位于对象上,而不是引用变量。您正在创建两个对象,因此让我们将它们命名为引用:
- 在字段初始值设定项中创建ObjA
- 在sleep(1000)
synchronized(a.lockObj)
块锁定在ObjA上
由于启动线程后您有sleep(100)
,因此当主线程到达其synchronized(a.lockObj)
块时,线程将更改a.lockObj
以引用ObjB,从而将锁定到不同的对象上
作为不同的对象,代码不会阻塞
提示:锁位于对象上,而不是引用变量。您的两个线程使用不同的锁。第一个线程保存a.lockObj引用的第一个对象实例,第二个线程保存a.lockObj引用的第二个对象实例。这是很容易避免的:不要重新分配正在同步的对象。另一个答案中的一些措辞让我感到困惑,特别是“reference”一词的使用,让我们称该成员为a.lockObja reference;
a.lockObj
引用的对象是引用对象。同步取决于引用的对象,而不是引用。有两个不同的引用对象用于同步;结果很糟糕。您的两个线程使用了不同的锁。第一个线程保存a.lockObj引用的第一个对象实例,第二个线程保存a.lockObj引用的第二个对象实例。这是很容易避免的:不要重新分配正在同步的对象。另一个答案中的一些措辞让我感到困惑,特别是“reference”一词的使用,让我们称该成员为a.lockObj
a reference;a.lockObj
引用的对象是引用对象。同步取决于引用的对象,而不是引用。有两个不同的引用对象用于同步;结果是悲惨的。
from first block start
0
from second block start
from second block done
1
1
from first block done