Como posso criar uma instância simultânea de List, onde posso acessar elementos por índice? O JDK tem alguma classe ou método de fábrica que eu possa usar?
java
list
concurrency
AlikElzin-kilaka
fonte
fonte
List
daquelas especificamente especificadas no original. diz que é um requisito considerado vandalismo. Um moderador já bloqueou a pergunta por causa das pessoas que estão reclamando que as respostas não respondem a essa versão vandalizada da pergunta.locked
/closed
/ comentário anteriorRespostas:
Há uma implementação de lista simultânea em java.util.concurrent . CopyOnWriteArrayList em particular.
fonte
Se você não se preocupa em ter acesso baseado em índice e apenas deseja as características de preservação da ordem de inserção de uma Lista, considere um java.util.concurrent.ConcurrentLinkedQueue . Como ele implementa o Iterable, quando você terminar de adicionar todos os itens, poderá percorrer o conteúdo usando a sintaxe aprimorada:
fonte
:
) é chamado de foreach: docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.htmlÉ possível usar muito bem o Collections.synchronizedList (List) se tudo o que você precisa é de simples sincronização de chamada:
fonte
synchronizedList
é "sincronizado", mas não "simultâneo". Uma questão fundamental que muitas operações da Lista - que são baseadas em índices - não são atômicas e precisam fazer parte de uma construção de exclusão mútua maior.Vector
é mais simples do queCollections.synchronizedList(new ArrayList<Object>())
.Como o ato de adquirir a posição e obter o elemento da posição especificada requer naturalmente algum bloqueio (não é possível que a lista tenha alterações estruturais entre essas duas operações).
A própria idéia de uma coleção simultânea é que cada operação por si só é atômica e pode ser feita sem bloqueio / sincronização explícita.
Portanto, colocar o elemento na posição
n
de uma dadaList
operação atômica não faz muito sentido em uma situação em que o acesso simultâneo é antecipado.fonte
Você tem estas opções:
Collections.synchronizedList()
: Você pode envolver qualquerList
aplicação (ArrayList
,LinkedList
ou uma lista de 3rd-party). O acesso a todos os métodos (leitura e escrita) será protegido usandosynchronized
. Ao usariterator()
ou aprimorado para o loop, você deve sincronizar manualmente; durante a iteração, outros threads são totalmente bloqueados, mesmo na leitura. Você também pode sincronizar separadamente para cada chamadahasNext
enext
, masConcurrentModificationException
é possível.CopyOnWriteArrayList
: é caro modificar, mas não tem espera para ler. Os iteradores nunca lançamConcurrentModificationException
, eles retornam um instantâneo da lista no momento da criação do iterador, mesmo que a lista seja modificada por outro encadeamento durante a iteração. Útil para listas atualizadas com pouca frequência. Operações em massa comoaddAll
as preferidas para atualizações - a matriz interna é copiada menos vezes.Vector
: muito parecidosynchronizedList
, mas a iteração também é sincronizada. No entanto, os iteradores podem lançarConcurrentModificationException
, se o vetor for modificado por outro thread durante a iteração.Outras opções:
Collections.unmodifiableList()
: livre de trava, sem fio, mas não modificávelQueue
ouDeque
pode ser uma alternativa se você adicionar / remover apenas no final da lista e iterar a lista. Não há acesso por índice nem adição / remoção em locais arbitrários. Eles têm várias implementações simultâneas com melhor desempenho e melhor acesso simultâneo, mas está além do escopo desta pergunta. Você também pode dar uma olhada no JCTools , eles contêm implementações de filas com melhor desempenho, especializadas para um único consumidor ou produtor único.fonte
O CopyOnWriteArrayList é uma alternativa simultânea da interface List implementada e a parte sincronizada do pacote java.util.concurrent e é uma coleção segura para threads.
CopyOnWriteArrayList é à prova de falhas e não lança ConcurrentModificationException quando CopyOnWriteArrayList subjacente é modificado durante a Iteração, use uma cópia separada de ArrayList.
Isso geralmente é muito caro, porque a matriz de cópias envolve todas as operações de atualização em que uma cópia clonada será criada. CopyOnWriteArrayList é a melhor opção apenas para operação de leitura frequente.
http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/CopyOnWriteArrayList.html
https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/CopyOnWriteArrayList.html
fonte