gme*_*mon 6 java concurrency multithreading synchronized synchronized-block
假设我有一个对象如下:
Map<String, String> m = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)
然后我按如下方式同步该对象并更改其引用:
synchronize(m){
m = new HashMap<>();
}
Run Code Online (Sandbox Code Playgroud)
有了这段代码,m 上的锁会发生什么情况?更新 m 代表的新对象是否仍然安全?或者锁本质上是在旧对象上?
从JLS 17.1开始:
\n\n\n\n\n同步语句 (\xc2\xa714.19) 计算对对象的引用;\n 然后它尝试在该对象的监视器上执行锁定操作,并且\n 在锁定操作成功之前不会继续执行\n完全的。执行锁定操作后,将执行同步语句的主体。如果主体的执行完成,无论是正常还是突然,都会在同一监视器上自动执行解锁操作。
\n
现在问题来了。
\n\nm 上的锁会发生什么情况?
\n\n没有什么。这有点令人困惑。实际上,线程在尝试获取锁时持有所引用的对象的锁。 m同步块中的分配m不会自动“切换”执行线程所持有的锁。
更新 m 代表的新对象是否仍然安全?
\n\n这不安全。同一锁上的写入m不同步。
或者锁本质上是在旧对象上?
\n\n是的
\n