Moja pula wątków ma stałą liczbę wątków. Wątki te muszą często pisać i czytać z udostępnionej listy.
Jaka więc struktura danych (lepiej lista, musi być wolna od monitora) w java.util.concurrent
pakiecie jest najlepsza w tym przypadku?
java
concurrency
象 嘉 道
źródło
źródło
List
.ConcurrentModificationException
Może nie pochodzić z problemem synchronizacji; pojawia się również na przykład w pętli for nad kolekcją, w której próbujesz usunąć element z kolekcji.Vector
?Odpowiedzi:
Tylko
List
realizacja wjava.util.concurrent
to CopyOnWriteArrayList . Istnieje również opcja zsynchronizowanej listy, o której wspomina Travis Webb.To powiedziawszy, czy na pewno potrzebujesz, aby to był
List
? Istnieje o wiele więcej opcji dla współbieżnychQueue
s iMap
s (i można utworzyćSet
s zMap
s), a te struktury mają zwykle największy sens w przypadku wielu rodzajów rzeczy, które chcesz zrobić ze wspólną strukturą danych.W przypadku kolejek masz ogromną liczbę opcji i to, która z nich jest najbardziej odpowiednia, zależy od tego, jak chcesz z niej skorzystać:
źródło
CopyOnWriteArrayList
ma tę wadę, że jest bardzo kosztowny przy zapisie (ale tani jak na odczyt). Jeśli robisz dużo zapisów, lepiej będzie mieć zsynchronizowaną listę lub kolejkę.Dowolną kolekcję Java można ustawić jako bezpieczną dla wątków, na przykład:
List newList = Collections.synchronizedList(oldList);
Lub utworzyć zupełnie nową listę bezpiecznych wątków:
List newList = Collections.synchronizedList(new ArrayList());
http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)
źródło
ConcurrentHashMap
chociażCollections.synchronizedMap
metoda.ConcurrentHashMap
. Szczegóły implementacji synchronizacji są różne. używanie tychsynchronized
metod wCollections
zasadzie po prostu opakowuje klasę w monitorze Java.ConcurrentHashMap
wykorzystuje bardziej inteligentne funkcje współbieżności.Jeśli rozmiar listy został ustalony, możesz użyć AtomicReferenceArray . Umożliwiłoby to wykonanie indeksowanych aktualizacji slotu. W razie potrzeby możesz napisać widok listy.
źródło
Możesz spojrzeć na ConcurrentDoublyLinkedList napisaną przez Douga Leę na podstawie „Praktycznej listy podwójnie połączonej bez blokad” Paula Martina. Nie implementuje interfejsu java.util.List, ale oferuje większość metod, których można użyć na liście.
Według javadoc:
źródło
ConcurrentLinkedQueue
używa kolejki bez blokady (opartej na nowszej instrukcji CAS ).źródło
List
interfejsu.List.set(int index, Object element)
z ConcurrentLinkedQueue?List
metod specyficznych albo nie będzie możliwa do zaimplementowania przy użyciuQueue
(na przykład dodawania / ustawiania w określonym indeksie) lub może zostać zaimplementowana, ale będzie nieefektywna (pobierz z indeksu). Więc nie sądzę, żebyś naprawdę mógł to opakować. To powiedziawszy, myślę, że sugestia aQueue
jest w porządku, ponieważ OP tak naprawdę nie wyjaśnił, dlaczego potrzebująList
.Jeśli set jest wystarczający, można użyć ConcurrentSkipListSet . (Jego implementacja jest oparta na ConcurrentSkipListMap, która implementuje listę pominięć ).
Oczekiwany średni koszt czasu to log (n) dla operacji zawierania, dodawania i usuwania; metoda rozmiaru nie jest operacją działającą w czasie stałym.
źródło