Java 通过此vs虚拟对象进行同步

Java 通过此vs虚拟对象进行同步,java,multithreading,synchronization,thread-safety,synchronized,Java,Multithreading,Synchronization,Thread Safety,Synchronized,到目前为止,我已经看到了同步块的用法,但最近我了解到使用虚拟对象更可取。我发现以下主题与此相关 作为总结,在下面的代码中,两个不同的对象不能同时运行addA和addB,因为这两个对象都使用这个锁 private int a; private int b; public synchronized void addA(){ a++; } public synchronized void addB(){ b++; } 如果我使用dummy对象进行锁定,我会感到困惑,如果我在两种

到目前为止,我已经看到了同步块的用法,但最近我了解到使用虚拟对象更可取。我发现以下主题与此相关

作为总结,在下面的代码中,两个不同的对象不能同时运行addA和addB,因为这两个对象都使用这个锁

private int a;
private int b;

public synchronized void addA(){
    a++;
}

public synchronized void addB(){
    b++;
}
如果我使用dummy对象进行锁定,我会感到困惑,如果我在两种方法中都使用下面的行进行同步,会有什么不同?因为他们仍然有相同的锁

synchronized(dummyObject){
    ...
}
那么,这意味着我应该为每个方法使用两个不同的虚拟对象来与Synchronized as一起使用,这意味着什么呢

 public void addA(){
    synchronized(dummyObj1){
       a++;
    }
}

public void addB(){
    synchronized(dummyObj2){
       b++;
    }
}

这正是锁定对象的要点——您可以为不同的操作使用不同的锁定。假设同时运行
addA
addB
是有意义的(从外观上看,它肯定是有意义的),那么您确实应该有两个单独的锁,每个方法一个锁。

您是正确的。在这种情况下,需要两个不同的对象分别在其上同步

为了锁定,最简单的方法是创建
对象
对象

Object lock1 = new Object();
Object lock2 = new Object();

但如果我在同步的内部更改lock1对象引用会发生什么?为什么要更改lock1对象引用?为了确保不可能更改这些引用(因为更改它们没有意义),您可以在声明这些对象时添加最终修饰符。这是一个开放式问题,但理论上您可以对
a
b
本身进行同步(如果它们是
对象
s).@D.Kovács
a
b
是原语。你需要一个对象来同步。@Mureinik我几乎立刻就编辑了一个对象,关于这个;)@D.Kovács我想我太慢了:-)@Mureinik顺便说一句,永远不要忘记不应该在盒装原语上同步: