2015-09-21 14 views

Odpowiedz

0

CopyOnWriteArrayList

Instancja CopyOnWriteArrayList zachowuje się jak listy, która umożliwia realizację wielu jednoczesnych czyta, czyta i występuje równocześnie z zapisu. W ten sposób tworzy się zupełnie nową kopię listy za każdym razem, gdy zostanie zmieniona.

  1. Odczyty nie blokują i skutecznie płacą tylko koszt zmiennego odczytu.
  2. Zapisy nie blokują odczytów (lub odwrotnie), ale może nastąpić tylko jedno zapisanie.
  3. W przeciwieństwie do ConcurrentHashMap, operacje zapisu, które zapisują lub uzyskują dostęp do wielu elementów na liście (takich jak addAll(), retainAll()) będą atomowe.

Podczas operacji zapisu tablica musi być całkowicie zablokowana względem innych zapisów. (Standardowa implementacja używa ReentrantLock.) Jednakże, jak wspomniano, operacje mające wpływ na wiele lokalizacji mogą być atomowe. Oznacza to, że jeśli jeden wątek dodaje kilka elementów do listy za pomocą metody addAll(), podczas gdy inny wątek wywołuje size(), wątek odczytujący rozmiar otrzyma wartość, która odzwierciedla liczbę elementów dodanych w addAll(): lub nie. "nie będzie możliwości otrzymania wartości pośredniej zwróconej (oczywiście pod warunkiem, że są to jedyne dwa wątki uzyskujące dostęp do listy!).

CopyOnWriteArrayList przeznaczony jest do przypadków, w których reads hugely outnumber writes.

CopyOnWriteArraySet

Inna klasa, CopyOnWriteArraySet jest zbudowany na szczycie CopyOnWriteArrayList. Podobnie jak jego odpowiednik w liście, jest przeznaczony dla przypadków, w których zestaw zawiera tylko kilka elementów, a liczba odczytów znacznie przewyższa liczbę zapisów.

referencyjny: Java copy-on-write collections

+0

Jak działa mechanizm blokujący w tym przypadku? Na przykład Jeśli wątek przechodzi przez listę, czytając pozycje na liście, to uzyskałby on blokadę na obiekcie listy i podczas jej pozyskiwania blokady, jak mógłby to odczytać inny wątek? Dlaczego lektury nie blokują? – prvn

+0

Do odczytu nie nabywa blokady. Blokada jest używana tylko wtedy, gdy aktualizacja odbywa się w tablicy. – YoungHobbit

+0

[get()] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/CopyOnWriteArrayList.java#CopyOnWriteArrayList.get% 28int% 29) metoda nie ma żadnych blokad, gdzie jako [zestaw()] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/CopyOnWriteArrayList.java#CopyOnWriteArrayList.set%28int%2Cjava.lang.Object%29) najpierw nabyć blokadę następnie przetwarzane. – YoungHobbit

1

Sposób, w jaki sposób to zrobić nowiutki odpisu listy za każdym razem, gdy jest zmieniony.

Odczyty nie blokują i skutecznie płacą tylko koszt zmiennego odczytu. Zapisy nie blokują odczytów (lub odwrotnie), ale może nastąpić tylko jedno zapisanie.

Powiązane problemy