我有一张图表。此图包含具有以下内容的节点类:
public abstract class AbstractNode{
public Collection<AbstractNode> predecessors;
public Collection<AbstractNode> successors;
//accept methods for visitors
}
我最近添加了一个允许您从YAML文件导入配置的组件。该组件读取YAML文件并使用此节点类生成图形。这段代码相当慢,并且在图表上进行了大量操作,包括通过一些前辈进行分析,分析各种节点,以及决定如何更新其他节点后继者和/或前任者。
我们现有的代码有一项服务,每隔100毫秒轮询一次这个图表,使用访问者在我们的程序中生成错误列表。访问者实际上是一类对象,每次都会通过每一个后继者和前辈列表。
这会导致并发修改异常。 :(
我的选择似乎是:
close()
调用或hasNext()
返回false。这将允许我们阻止作者直到读者完成。
CopyOnWriteArrayCollection
作为其前驱和后继的后备集/列表
List<String> predecessors = new ArrayList<>()
List<String> predecessors = new CopyOnWriteArrayList<>()
代码
我真正想要的是一个围绕组合而不是继承而构建的集合框架。
要把它变成一个咆哮一秒钟,并且有很多后见之明的好处,它很好地认识到当面对创建抽象类和它们的多个实现的选择时,或者一个代表的类依赖性(读取:由其依赖性组成),后者是普遍优选的。
没有图书馆允许我做像
这样的事情private final Collection<AbstractNode> predecessors = Collections.create(
DuplicationPolicies.ForbidDuplicates,
Orders.InsertionOrder,
Concurrency.ThrowOnConcurrentModification
);
表示LinkedHashSet<>
和
private final Collection<AbstractNode> predecessors = Collections.create(
DuplicationPolicies.AllowDuplicates,
Orders.InsertionOrder,
Concurrency.CopyOnWrite
);
表示CopyOnWriteArrayList<>
?
使用这样的系统,(可能)对于我来说,从并发反向实现(例如ArrayList)切换到兼容并发的实现(例如CopyOnWrite列表或共享/独占 - )是相当简单的。锁定列表)。
答案 0 :(得分:1)
在java中还没有复合集合,但您可以使用标准java集合和一些其他对象作为类的成员轻松地实现它们。
由于您始终使用Orders.InsertionOrder
策略,因此类似列表的基本集合最适合您。您可以使用CopyOnWriteArrayList
作为实施Concurrency.CopyOnWrite
政策的基本集合,使用简单ArrayList
作为实施Concurrency.ThrowOnConcurrentModification
。
对于使用单DuplicationPolicies
方法的bool canAddElem(collection, elem)
其他对象就足够了。
类似的东西:
public class CompositeCollection extends Collection<AbstractNode>
{
private Collection<AbstractNode> baseCollection;
private filter;
public CompositCollection(DuplicationPolicies dPolicy, Concurrency cPolicy)
{
if(dPolicy == DuplicationPolicies.AllowDuplicates)
{
filter = new AllowDuplicatesFilter();
}
else
{
filter = new ForbidDuplicatesFilter();
}
if(cPolicy == Concurrency.Concurrency.CopyOnWrite)
{
baseCollection = new CopyOnWriteArrayList<AbstractNode>();
}
else
{
baseCollection = new ArrayList<AbstractNode>();
}
}
public bool add(AbstractNode node)
{
if(!filter->canAddElem(baseCollection, node)) {return false; }
return baseCollection->add(node);
}
...
};