Java的.如何正确同步getter和setter?

Jak*_*ake 10 java synchronization

如果我在一个对象中有几个可变属性,将由多个线程执行,我知道它们应该是同步的.

class Doggie {
    private String name;
    private int    age;

    public void setName(String name) { this.name = name; }
    public String getName() { return this.name; }
    public void setAge(int age) { this.age = age; }
    public int getAge() { return this.age; }

}
Run Code Online (Sandbox Code Playgroud)

问题:

  • 是不是return和Java一起分配原子操作?
  • 由于属性可能不一定是相互关联的,因此与同一锁同步并不总是有意义的.如何组织锁定结构?
  • 使用内部锁或私有对象锁模式更好吗?

Ste*_*n C 10

  • Java中是不是返回和赋值原子操作?

是的,它们是原子的(至少在某些情况下),但原子性不是唯一的问题.另一个重要的问题是,一个线程对属性的写操作是否保证对于由不同线程产生的相同属性的后续读取是可见的.

  • 当读写在同一个线程中时,读保证会看到先前的写操作.

  • 当读取和写入位于不同的线程中时,如果两个线程正确同步,或者如果声明属性,则只能保证读取先前的写入volatile.

请注意,原始锁/互斥锁不是同步的唯一方法.

  • 由于属性可能不一定是相互关联的,因此与同一锁同步并不总是有意义的.如何组织锁定结构?

如果(并且仅当)可能存在锁争用,则使用多个锁是有意义的.在您的示例中,如果某些Doggie实例接收到非常高的get和/或set操作率,则锁争用可能只是一个问题.

  • 使用内部锁或私有对象锁模式更好吗?

这取决于.如果您的应用程序正在使用Doggie对象的原始锁定,那么您可能会遇到锁争用甚至意外锁定get和set操作.在这种情况下,建议使用私人锁.否则,私有锁是一种不必要的开销.