小编kha*_*set的帖子

使用修饰符创建不可变类的好方法(线程安全)

我有一个案例,当我想避免防御性副本,对于可能仍然被修改的数据,但通常只是阅读,而不是写入.所以,我想使用不可变对象,使用函数mutator方法,这是常见的(java lombok能够或多或少地自动执行).我进行的方式如下:

public class Person {
    private String name, surname;
    public Person(String name, String surname) {....}
    // getters...

    // and instead of setters
    public Person withName(String name) {
       Person p= copy(); // create a copy of this...
       p.name= name;
       return p;           
    }

   public Person copy() {....}         
}
Run Code Online (Sandbox Code Playgroud)

因此,要获得具有不同名称的人的副本,我会打电话

p= new Person("Bar", "Alfred");
...
p= p.withName("Foo");
Run Code Online (Sandbox Code Playgroud)

在实践中,对象相当大(我最终使用序列化来避免编写复制代码的负担).

现在,在浏览网页时,我发现这个实现存在潜在的并发问题,因为我的字段不是最终的,因此,并发访问可能会看到返回的副本,例如,没有新的名称更改(因为没有保证在这种情况下的操作顺序).

当然,我无法使用当前实现将我的字段设为最终,因为我先复制,然后更改副本中的数据.

所以,我正在为这个问题寻找一个好的解决方案.

我可能会使用volatile,但我觉得这不是一个好的解决方案.

另一种解决方案是使用构建器模式:

class PersonBuilder {
   String name, surname; ....
}

public class Person {
   private final String name, surname;

   public Person(PersonBuilder …
Run Code Online (Sandbox Code Playgroud)

java multithreading final volatile immutability

6
推荐指数
1
解决办法
807
查看次数

标签 统计

final ×1

immutability ×1

java ×1

multithreading ×1

volatile ×1