Java类不可变与线程安全集合

时间:2015-07-04 14:04:18

标签: java multithreading thread-safety immutability

假设我有以下课程:

public final class Person {

   final private String personFirstName;
   final private String personLastName;
   final private ConcurrentMap<Double, String> phoneMessages;

    public Person(String firstname, String lastname) {
       phoneMessages = new ConcurrentHashMap<Double, String>();
       this.personFirstName = firstname;
       this.personLastName = lastname;
    }

    public void add(Double key, String item) {
        phoneMessages.put(key, item);
    }

    public String getPersonFirstName() {
        return personFirstName;
    }

    public String getPersonLastName() {
        return personLastName;
    }

}

即使我创建了一个带有私有的最终线程安全集合的类,我的类是不可变的吗?我的猜测是否定的。

如果在对象中拥有一个集合是不正确的,那么Java中的正确做法是什么?我如何设计包含集合的类?

1 个答案:

答案 0 :(得分:0)

正如其他人所指出的那样, 你如何使用你的类将决定是否使其成为不可变的。

也就是说,这个版本的Person类是不可变的:

public final class Person {

   final private  String personFirstName;
   final private  String personLastName;
   final private ConcurrentMap<Double,String> phoneMessages;

    public Person(String firstname, String lastname) {
       this.phoneMessages = new ConcurrentHashMap<Double,String> ();
       this.personFirstName = firstname;
       this.personLastName  = lastname;
    }

    private Person(String firstname, String lastname, ConcurrentHashMap<Double,String> phoneMessages) {
       this.personFirstName = firstname;
       this.personLastName  = lastname;
       this.phoneMessages = phoneMessages;
    }

    public Person add(Double Key, String item){
        ConcurrentHashMap<Double, String> newMap = new ConcurrentHashMap<>(this.phoneMessages);
        newMap.put(Key, item);
        return new Person(this.personFirstName, this.personLastName, newMap);
    }

    public String getPersonFirstName() {
        return personFirstName;
    }

    public String getPersonLastName() {
        return personLastName;
    }

    public Map<Double, String> getPhoneMessages() {
        return Collections.unmodifiableMap(this.phoneMessages);
    }

}

请注意,add方法返回Person的不同实例,以便当前Person实例保持不变(不可变)。