Meu pool de threads tem um número fixo de threads. Esses tópicos precisam escrever e ler de uma lista compartilhada com frequência.
Portanto, qual estrutura de dados (melhor ser uma lista, deve ser sem monitor) no java.util.concurrent
pacote é a melhor neste caso?
java
concurrency
象 嘉 道
fonte
fonte
List
.ConcurrentModificationException
pode não vir de um problema de sincronização; também surge, por exemplo, em um loop for sobre uma coleção, onde você tenta remover um elemento da coleção.Vector
?Respostas:
A única
List
implementação emjava.util.concurrent
é CopyOnWriteArrayList . Também existe a opção de uma lista sincronizada, como Travis Webb menciona.Dito isso, tem certeza de que precisa que seja um
List
? Existem muito mais opções paraQueue
s e s simultâneosMap
(e você pode fazerSet
s a partir deMap
s), e essas estruturas tendem a fazer mais sentido para muitos dos tipos de coisas que você deseja fazer com uma estrutura de dados compartilhada.Para filas, você tem um grande número de opções e a mais adequada depende de como você precisa usá-la:
fonte
CopyOnWriteArrayList
tem a desvantagem de ser muito caro na gravação (mas barato para leituras). Se você estiver fazendo muitas gravações, será melhor usar uma lista sincronizada ou uma fila.Qualquer coleção Java pode ser feita para ser thread-safe, como:
List newList = Collections.synchronizedList(oldList);
Ou para criar uma nova lista de thread-safe:
List newList = Collections.synchronizedList(new ArrayList());
http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)
fonte
ConcurrentHashMap
embora haja umCollections.synchronizedMap
método.ConcurrentHashMap
. Os detalhes da implementação da sincronização são diferentes. usar ossynchronized
métodosCollections
basicamente envolve a classe em um monitor Java.ConcurrentHashMap
usa recursos de simultaneidade mais inteligentes.Se o tamanho da lista for fixo, você poderá usar um AtomicReferenceArray . Isso permitiria a você realizar atualizações indexadas em um slot. Você pode escrever uma exibição de lista, se necessário.
fonte
Você pode querer dar uma olhada em ConcurrentDoublyLinkedList escrito por Doug Lea com base na "A Practical Lock-Free Doubly-Linked List" de Paul Martin. Ele não implementa a interface java.util.List, mas oferece a maioria dos métodos que você usaria em uma Lista.
De acordo com o javadoc:
fonte
ConcurrentLinkedQueue
usa uma fila livre de bloqueio (com base na instrução CAS mais recente ).fonte
List
interface.List.set(int index, Object element)
com ConcurrentLinkedQueue?List
métodos específicos não serão implementados usando umQueue
(adicionar / definir em um índice específico, por exemplo) ou podem ser implementados, mas serão ineficientes (obter de um índice). Então eu não acho que você poderia realmente embrulhar isso. Dito isso, acho que a sugestão de aQueue
está bem, pois o OP não explicou realmente por que eles precisam de aList
.Se definido for suficiente, ConcurrentSkipListSet pode ser usado. (Sua implementação é baseada em ConcurrentSkipListMap, que implementa uma lista de pular .)
O custo de tempo médio esperado é log (n) para as operações de contém, adiciona e remove; o método de tamanho não é uma operação de tempo constante.
fonte