альтернатива CopyOnWriteArrayList для частых записей, периодических итераций - PullRequest
14 голосов
/ 20 мая 2011

У меня есть ArrayList, который должен кэшироваться и совместно использоваться несколькими потоками на неопределенный срок. Операции включают частые добавления и удаления, а также итерации по нему.

ArrayList живет в классе-обёртке, который управляет доступом к нему:

public class MyListWrapper<T> implements Iterable<T> {

    private List<T> innerList = new ArrayList<T>();

    public Iterator<T> iterator() {
        return innerList.listIterator();
    }

    public void add(T element) {
        innerList.add(element);
        //app-specific logic
    }

    //remove(T), etc in the same pattern...
}

Я сейчас готовлюсь к безопасности ниток. Поначалу CopyOnWriteArrayList казался лучшим ответом, но его производительность меня беспокоит, поскольку изменения будут производиться чаще, чем все остальное.

Будет ли ручное изменение класса обертки, например, лучшим вариантом?:

public Iterator<T> iterator() {
    return new ArrayList<T>(innerList).listIterator();
}

//plus concurrency tweaks for any non-atomic modifications to innerList

Пожалуйста, помогите мне найти лучший подход.

Ответы [ 2 ]

8 голосов
/ 20 мая 2011

Вы можете попробовать использовать Collections.newSetFromMap(new ConcurrentHashMap<T, Boolean>());. Это даст вам одновременный набор хэшей, который даст вам около O (1) для добавления и удаления.

5 голосов
/ 20 мая 2011

Можно использовать ConcurrentLinkedQueue, если вы можете жить с интерфейсом очереди вместо списка. Я бы сказал, что больше вариантов использования, чем вы ожидаете, могут быть удовлетворены очередью. Одним из ключевых преимуществ List является произвольный доступ (на основе индекса), но в параллельной ситуации произвольный доступ не является ни необходимым, ни желательным.

ConcurrentLinkedQueue является отличной параллельной реализацией очереди.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...