Threadsafe collection typu ArrayList

0

Zastanawiam się nad tym jak najlepiej tworzyć bezpieczną kolekcję która działa jak ArrayList
Słyszałem że Vector jest niezbyt udana i się nie powinno jej stosować.
Teraz są takie możliwości
-użycie CopyOnWriteArrayList
-użycie metody synchronizedlist
-ew. atomic reference

W moim przypadku tworzę statyczną kolekcję w mainie i przekazuje jej referencję do nowych wątków gdzie wywołuje 1 operacje dodania a tak to następuje głównie czytanie z tej kolekcji.
Rozumiem że w tym przypadku najlepiej jest zastosowac CopyOnWriteArrayList zakładając małą ilośc dodań nowych obiektów do kolekcji?
Ewentualnie rozumiem że można na początku użyć synchronizedlist np.

 
List<JakisTypt> objects = Collections.synchronizedlist(new ArrayList<JakisTyp>());

I wtedy od początku dana lista jest threadsafe i nie musze używac synchronized itp?

0

-użycie CopyOnWriteArrayList
-użycie metody synchronizedlist
-ew. atomic reference

nie ma prawa zadziałać tylko AtomicReference, bo to służy do czegoś innego.

AtomicReference<List<T>> notThreadSafe = new AtomicReference<>();

lista do ktorej referencje trzyma ten obiekt, sama w sobie nie jest bezpieczna.

0

To czego w takim razie służy Atomic Reference?

0

Rozumiem że w tym przypadku najlepiej jest zastosowac CopyOnWriteArrayList zakładając małą ilośc dodań nowych obiektów do kolekcji?

Tak, to byłby dobry wybór.

To czego w takim razie służy Atomic Reference?

Pozwala na atomowe ustawianie wartości, a poza tym również atomowe operacje takie jak getAndSet, compareAndSet, więc nie musisz martwić się o synchronizację dla nich.
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicReference.html

0

Od końca.

scibi92 napisał(a)

To czego w takim razie służy Atomic Reference?

Jest to interfejs do operacji typu CAS, czyli Compare And Swap. Jest to zestaw operacji na poziomie procesora (tak, na poziomie procesora z poziomu Javy), które chronią program wielowątkowy przed problemem Lost Update dla zmiennych ulotnych (volatile). Mówiąc prościej, jest to specjalna klasa, która pozwala na wykorzystanie mechanizmów synchronizacji danych w komputerach wieloprocesorowych.

scibi92 napisał(a)

Rozumiem że w tym przypadku najlepiej jest zastosowac CopyOnWriteArrayList zakładając małą ilośc dodań nowych obiektów do kolekcji?

CopyOnWriteArrayList będzie ok o ile jest niewiele do wstawiania. Przy czym niewiele oznacza raczej proporcję do odczytów, a nie liczbę operacji. Problemem może okazać się też pamięciożerność tej struktury. Jeżeli nie jest to problem na poziomie algorytmu to lepiej użyć BlockingQueue/BlockingDeque, które są wygodniejsze w użyciu.

scibi92 napisał(a)

Ewentualnie rozumiem że można na początku użyć synchronizedlist np.

Oczywiście, ale struktury te są po pierwsze widokami, zatem jeżeli zmienisz oryginalną kolekcję to one też się zmienią. Po drugie synchronizacja jest na poziomie wszystkich operacji, co czyni całość powolną.

Pozostaje też samodzielna implementacja odpowiedniej struktury z użyciem np. Lock.

1

Ja bym w ogóle zaczął od tego czy poszczególne wątki maja widzieć zmiany w liście dokonywane przez inne wątki czy też mają ich nie widzieć. Bo przecież działanie CopyOnWriteArrayList jest zasadniczo różne od zwykłej listy synchronizowanej. W jednym przypadku każdy wątek generalnie będzie miał swoją własną listę (po tym jak coś spróbuje dodać) a w drugiej sytuacji lista będzie jedna i każdy będzie widział wszystkie dodawane elementy.

0

No ja chce zrobić tak że gdy jeden wątek który ma referencję do listy doda coś do niej to wtedy inne wątki to "zauważą"

2

To może własna struktura, która będzie implementować obserwatora?

0

Może skorzystaj z Guavy po prostu?

0

To juz prędzej wygląda jak jakaś implementacja TupleSpace, można by pewnie użyć też Hazecasta i jego rozproszonych kolekcji.

1 użytkowników online, w tym zalogowanych: 0, gości: 1