与虚拟对象同步,而不是与此对象同步

2022-09-04 07:15:49

我多次遇到过类似下面的代码

class Foo {
   private Object lock = new Object();

   public void doSomething() {
      synchronized(lock) {
         ...

我感兴趣的是为什么创建锁定对象而不是编写?是否启用共享锁?我依稀记得读到过这是一种优化。这是真的吗?另外,在某些情况下,将锁声明为有意义吗?synchronized(this)final


答案 1
  1. 不建议在 上同步,因为如果对象本身用作来自外部的锁,则会中断内部同步。另外,请记住,方法也用作锁,这可能会导致不必要的效果。thissynchronizedthis
  2. 建议声明锁定,以防止在块内重新分配锁定对象的情况,从而导致不同的线程看到不同的锁定对象。请参阅另一个问题:锁定可变对象 - 为什么它被认为是一种不好的做法?finalsynchronized

答案 2

想象一下,您拥有并访问 和 访问 的场景。同步 on 将阻塞 和 如果 或 正在访问,这不应该发生,并且与 无关。对此的优化是使用两个不同的锁,而不是锁定整个类实例。thread1thread2method1thread3thread4method2thisthread3thread4thread1thread2method1thread3thread4method1

以下是我在JavaDoc上找到的一个很好的段落,它反映了这一点:

同步语句对于通过细粒度同步提高并发性也很有用。例如,假设类 MsLunch 有两个实例字段 c1 和 c2,它们从不一起使用。这些字段的所有更新都必须同步,但没有理由阻止 c1 的更新与 c2 的更新交错进行,这样做会通过创建不必要的阻塞来减少并发性。