2013-08-15 11 views
8

Mam tablicę, która zawiera wartości całkowite zadeklarowane tak:Czy jednoczesne odczyty z tablicy są bezpieczne dla wątków?

int data[] = new int[n]; 

Każda wartość musi być przetwarzane i jestem podział pracy na kawałki tak, że może być przetwarzany przez osobne wątki. Tablica nie zostanie zmodyfikowana podczas przetwarzania.

Czy wszystkie wątki przetwarzania mogą jednocześnie pobierać oddzielne części tablicy? Czy muszę użyć blokady?

Innymi słowy: czy to zamówienie jest bezpieczne w pracy?

Array is created and filled 
Threads are created and started 
Thread 0 reads data[0..3] 
Thread 1 reads data[4..7] 
Thread 2 reads data[8..n] 
+0

Dowolna liczba wątków może odczytywać wartości. Sekcje krytyczne mają znaczenie tylko w przypadku pisania. – Jyro117

+0

@ Jyro117 lub czytanie! Iteracja nad strukturą powinna być zsynchronizowana. –

+0

Jeśli twoja struktura jest traktowana jako niezmienna, tzn. Nie zapisuje danych wewnątrz lub samej struktury, nie musisz jej synchronizować. O ile twoja struktura się nie zmienia, kiedy czytasz z niego, ale w przypadku tablic, które nigdy się nie zdarzają. – Jyro117

Odpowiedz

6

odczytu zawartości tablicy (albo jakiegokolwiek innego zbioru, pola obiektu, etc.) przez wiele nitek wątku jest bezpieczny pod warunkiem, że dane nie są modyfikowane w czasie.

Jeśli wypełnisz tablicę danymi do przetworzenia i przekażesz je do różnych wątków do odczytu, dane zostaną poprawnie odczytane i żaden wyścig danych nie będzie możliwy.

Pamiętaj, że działa to tylko wtedy, gdy utworzysz gwinty po wypełnieniu tablicy. Jeśli przekażesz tablicę do przetworzenia do już istniejących wątków bez synchronizacji, zawartość tablicy może nie zostać odczytana poprawnie. W takim przypadku metoda, w której wątek uzyska odniesienie do tablicy, powinna być zsynchronizowana, ponieważ zsynchronizowany blok wymusza aktualizację pamięci między wątkami.

Na marginesie: używanie niezmiennej kolekcji może być dobrym pomysłem. W ten sposób zapewnisz, że żadna modyfikacja nie jest możliwa. Sugerowałbym używanie takiego opakowania. Sprawdź pakiet java.util.concurrent.atomic, powinno być coś, co możesz wykorzystać.

+0

Dzięki za szybką odpowiedź.Błąkałem się, jeśli możliwy jest również zwrot, że wątki mogą być w tym samym czasie. (Te wątki nigdy nie będą w prawo do tego samego indeksu) – user2342875

+0

@ user2342875 masz na myśli pisać? Jeśli piszemy do różnych lokalizacji pamięci z różnych wątków, nigdy nie będziesz mieć pewności, czy pamięć będzie poprawnie (z nową wartością) odczytywana z różnych wątków, jeśli nie używasz synchronizacji. Synchronizacja zapewnia również synchronizację pamięci między wątkami. – Dariusz

+0

@ user2342875 Przebudowałem swoją odpowiedź i wspomniałem o potencjalnej pułapce; weź to pod uwagę w swoim kodzie. – Dariusz

2

Dopóki wątki nie modyfikują zawartości w tablicy, dobrze jest odczytać tablicę z wielu wątków.

0

Jeśli upewnisz się, że wszystkie wątki właśnie czytają, wątek jest bezpieczny. Chociaż nie powinieneś polegać na tym fakcie, alone i spróbować uczynić swoją tablicę niezmienną za pomocą opakowania.

0

Oczywiście, jeśli po prostu chcesz go przeczytać, podczas tworzenia, przekaż tablicę do wątków. Nie będzie żadnego problemu, o ile nie będziesz go modyfikować.

0

Odczytywanie z tablicy tablicowej jest operacją bezpieczną dla wątków, ale jeśli modyfikujesz tablicę, rozważ użycie klasy AtomicIntegerArray.

0

Należy rozważyć zapełnienie formularza ConcurrendLinkedQueue i pobranie z niego każdej nici. Zapewniłoby to, że nie ma problemów z współbieżnością.

Twoje wątki będą wyciągać swoje dane z górnej części kolejki i przetwarzać je.

Powiązane problemy