Я столкнулся с проблемой производительности при реализации структуры данных не дублирующийся параллельный ArrayList (или 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
должен возвращать значение индекса немедленно, как только термин добавляется в NonDuplicateList
.
It seems that ConcurrentHashMap isn't suitable for this case, since it doesn't keep strong data consistency
- поясните пожалуйста. - person OldCurmudgeon   schedule 28.11.2016