Witam wszystkich,
mam problem związany z zaprojektowaniem aplikacji wielowątkowej. W uproszczeniu: chcę posortować dużą tablicę (długości N~10^6) obiektów w M wątkach (np. poprzez scalanie). Każdy z wątków operuje na swoim zakresie tablicy, zakresy nie zachodzą na siebie. Po zakończeniu działania wątków usługowych, uzyskuję tablicę częściowo posortowaną, którą już tylko scalam w wątku głównym.
Najprościej byłoby mi operować na 1 wspólnej tablicy, tym bardziej, że i tak taka tablica będzie mi potrzebna w innej części programu. Moje pytanie dotyczy wydajności takiego rozwiązania i ewentualnych błędów.
- Czy każdy z wątków może otrzymać kopię całej tablicy w pamięci lokalnej? Obawiam się, że to znacznie zwiększyłoby zużycie pamięci.
- Czy w wyniku synchronizacji (happens before) mogę utracić zmiany wprowadzone w części wątków? Wytłumaczę dokładniej:
//watek glowny
volatile MyObject[] tablica = new MyObject[N];
//....inicjalizacja tablicy
Worker[] watki = new Worker[M];
//...przydzielanie zakresow
for(int i=0;i<M;++i)watki[i].start();
for(int i=0;i<M;++i)watki[i].join();
//poniżej synchronizacja przez volatile
tablica = tablica;
//tablica widziana w wątku głównym będzie zawierała wszystkie zmiany
//czy tylko zmiany z ostatniego wątku usługowego (poprzednie zostaną nadpisane?)
//.....Watek uslugowy
private class Worker extends Thread{
public void run(){
//.....sortowanie na zakresie tablicy: tablica
}
Podsumowując, w przypadku kiedy każdy wątek posiada swoją kopię zmiennej w pamięci lokalnej, po czym następuje synchronizacja w zewnętrznym wątku, to która wartość jest widziana? I jak to się ma do zmian wprowadzonych na rozłącznych zakresach jednej tablicy?
Proszę o podpowiedź, bo utknąłem i nie wiem czy powinienem szukać innych rozwiązań.