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

Kar*_*elė 12 java multithreading synchronized

我遇到过以下几次代码

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

   public void doSomething() {
      synchronized(lock) {
         ...
Run Code Online (Sandbox Code Playgroud)

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

Tud*_*dor 23

  1. this不鼓励同步,因为如果对象本身被用作来自外部的锁,则会破坏内部同步.此外,请记住,synchronized方法也this用作锁,这可能会导致不必要的影响.
  2. final建议声明锁定以防止在synchronized块内重新分配锁定对象的情况,从而导致不同的线程看到不同的锁定对象.看到另一个问题:锁定一个可变对象 - 为什么它被认为是一个不好的做法?


GET*_*Tah 5

想象一下这样一个场景:您拥有thread1thread2可以访问method1thread3可以thread4访问method2。同步this会阻塞thread3thread4如果thread1thread2正在访问,method1这不应该发生,因为thread3thread4无关method1。对此的优化是使用两个不同的锁,而不是锁定整个类实例。

\n\n

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

\n\n
\n

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

\n
\n