提高非重复并发ArrayList的性能

时间:2016-11-28 15:43:09

标签: java multithreading arraylist concurrenthashmap

我在实现非重复并发ArrayList(或div#users-contain table th { border: 9px solid #eee; padding: .6em 120px; } div#users-contain table td { border: 9px solid #eee; padding: .6em 220px .6em 20px ; } )的数据结构时遇到了性能问题。

ConcurrentLinkedQueue

请注意,public class NonDuplicateList implements Outputable { private Map<Term, Integer> map; private List<Term> terms; public NonDuplicateList() { this.map = new HashMap<>(); this.terms = new ArrayList<>(); } public synchronized int addTerm(Term term) { //bad performance :( Integer index = map.get(term); if (index == null) { index = terms.size(); terms.add(term); map.put(term, index); } return index; } @Override public void output(DataOutputStream out) throws IOException { out.writeInt(terms.size()); for (Term term : terms) { term.output(out); } } } Term都会实现NonDuplicateList接口输出。

为了保持Outputable线程安全,我使用NonDuplicateList来保护方法synchronized,并且当前调用addTerm(Term)时性能与预期一样糟糕。

addTerm似乎不适合这种情况,因为它不能保持强大的数据一致性。知道如何在不失去线程安全性的情况下提高ConcurrentHashMap的性能吗?

编辑:

addTerm方法,即通过output的迭代,可能不是线程安全的,因为在同时调用NonDuplicateList后只有一个线程会访问此方法,但addTerm必须返回一旦将术语添加到addTerm中,就立即将索引值。

2 个答案:

答案 0 :(得分:0)

如果您可以牺牲ConcurrentHashMap返回类型,则有可能在您的实现中重用addTerm。您可以返回boolean而不是返回实际索引,这表示添加是成功还是生成重复。这还允许您删除方法同步并提高性能:

private ConcurrentMap<Term, Boolean> map;
private List<Term> terms;

public boolean addTerm(Term term) {
    Boolean previousValue = map.putIfAbsent(term, Boolean.TRUE);
    if (previousValue == null) {
        terms.add(term);
        return true;
    }
    return false;
}

答案 1 :(得分:0)

恐怕你不会在这里得到更快的解决方案。关键是在不需要时避免同步。如果你不介意弱一致性,使用ConcurrentHashMap迭代器可能比在创建迭代器时迭代或获取一致快照时阻止其他线程添加项目要便宜得多。

另一方面,当您需要同步和一致的迭代器时,您需要ConcurrentHashMap的替代方法。我想到的是java.util.Collections#synchronizedMap,但它在对象级别使用同步,因此每次读/写操作都需要获取锁,这是性能开销。

查看ConcurrentSkipListMap,它可以保证各种操作的平均O(log(n))性能。它还有许多ConcurrentHashMap没有的操作:ceilingEntry/KeyfloorEntry/Key等。它还维护一个排序顺序,如果你使用它,否则必须计算(费用显着) ConcurrentHashMap。也许有可能摆脱list + map并使用ConcurrentSkipListMap代替。可以使用ConcurrentSkipListMap api计算元素索引。