不可改变但可刷新的系列?

时间:2014-10-29 16:48:43

标签: java multithreading concurrency guava

我遇到的一个常见模式是需要从数据库中刷新像List或HashMap这样的集合,但不希望在刷新之间添加或删除值。

我最近在Google的Guava库中发现了ImmutableList和ImmutableMap,我很喜欢。但我不能做一个" clearAll()"在这些类型上也不会重新填充它们。但是我喜欢它,除此之外它们是不可改变的。

因此,如果我想强制执行这种模式"只在数据库刷新时使其变为可变,我想我每次都必须使用一个volatile变量?还是有更好的模式?这也可以在多线程环境中,我会确保刷新()上没有竞争条件;

 public class MarketManager {

     private volatile ImmutableList<Market> markets = null;

     private MarketManager() { 
     }

     public void refresh() { 
         marketList = //build a new immutable market list
     }

     public static MarketManager getInstance() { 
         MarketManager marketManager = new MarketManager();
         marketManager.refresh();
         return marketManager;
     }
}

2 个答案:

答案 0 :(得分:3)

以下是您为类编写代码以便使用Collections.unmodifiableList()

的方法
public class MarketManager {

     private volatile List<Market> markets = Collections.emptyList();

     private MarketManager() { 
     }

     public void refresh() { 
         marketList = //build a new market list
     }

     public List<Market> getMarkets() {
         return Collections.unmodifiableList(markets);
     }

     // ...
}

Collections.unmodifiableList()只包含任何List实现,以便所有变异操作都被“禁用”(即,它们会抛出异常)。

答案 1 :(得分:1)

我认为您正在尝试将两个概念混合在一起:不可修改的对象和不可变对象。

不可修改的对象是您无法修改的对象。但是,它们可以在你下面改变#34;其他演员。当您需要控制对对象内部状态的访问时,此类对象非常有用。但是,它们对于线程安全或优化没有用。

不可变对象是真正不可变的。一旦创建,它们就无法更改。不是你,不是任何人。它们提供了不可修改对象的所有优点,而且它们允许优化并保证线程安全。

你提出的建议是将不可变的集合(创建和冻结)变为不可修改的集合(我无法对其进行更改,但可以从数据库中刷新)。只需使用Java中的不可修改的集合框架,就不需要修改Guava不可变集合。