用不可变类保证并发访问的安全性

不可变类

谷歌的guava工具集合为我们提供了不可变的集合类。
例如:

  • com.google.common.collect.ImmutableMap
  • com.google.common.collect.ImmutableList
  • com.google.common.collect.ImmutableSet

等等。
我们可以使用这些类来保证我们提供给调用方的数据是不可以改变的,从而保证我们的数据的安全性。

原子访问引用类型

根据 Effective Java 的原则 66-同步访问共享的可变数据,

我们使用一些配置信息集合,公共常量集合的时候,应该尽量使用不可变类。

并且还要保证,在动态的重新加载这些信息的时候,保证用户访问不会出现并发问题。

下面我们来结合下面的的引用原子类型来做一个小例子来演示这个原则。

  • java.util.concurrent.atomic.AtomicReference
package com.geh.learn.guava;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;

import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Immutable Collection Show Case
 *
 * @author 戈輝
 */
public class ShowImmutableCase {

    private static final AtomicReference> userMapRef = new AtomicReference<>(ImmutableMap.of());

    static {
        init();
    }

    /**
     * user info init
     */
    public static void init() {
        // 下面的处理实际可能从数据库或者可变的配置文件中读取 
        User user01 = new User("userKaki01", "東京");
        User user02 = new User("userKaki02", "大阪");
        Map userMap = Maps.newHashMap();
        userMap.put(user01.getUsername(), user01);
        userMap.put(user02.getUsername(), user02);
        
        // 初始化可以对外访问的集合类型
        userMapRef.set(ImmutableMap.copyOf(userMap));
    }

    public static void main(String[] args) {
        System.out.println("userKaki01 exist ? : " + userMapRef.get().containsKey("user01"));
    }
}

class User {

    private String username;

    private String address;

    public User(String username, String address) {
        this.username = username;
        this.address = address;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

你可能感兴趣的:(用不可变类保证并发访问的安全性)