我遇到的一个常见模式是需要从数据库中刷新像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;
}
}
答案 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不可变集合。