Wyznaczanie max za pomocą wątków

0

Witam.

Potrzebuję pomocy z pewnym zadaniem. Najpierw trzeba stworzyć tablicę N- elementową, następnie elementy tablicy należy podzielić na liczbę wątków(W). Każdy wątek wyznacza wartość max w swojej podtablicy, a po zakończeniu pracy wszystkich wątków należy wyznaczyć wartość max spośród wszystkich wartości max wyznaczonych przez wątki. Dodam, że wartości N i W podaje użytkownik.

Może ktoś ma pewien pomysł jak to można zrobić?

0

o_O? Przecież dokładnie opisałeś jak należy to zrobić. W czym problem? Masz 100 elementową tablicę, odpalasz np. 25 wątków każdy dla 4 elementów. Po takiej operacji masz 25 elementów na których odpalasz np. 5 wątków i to daje ci 5 elementów na których odpalasz jeszcze jeden wątek który wybiera globalnego maxa.

0

Problem w tym, że liczbę wątków należy podać tylko raz. Poza tym, 100 el tablicy łatwo jest podzielić na 25 wątków, a jak by było gdyby l. elem tablicy nie dzieliła się przez liczbę podanych przez użytkownika wątków?

1

Przecież podtablice nie muszą być takie same. Liczysz N/W i N%W. Pierwsze N%W podtablic zawiera N/W+1 elementów, pozostałe N/W elementów.

0

A można prosić o kod, żeby to jakoś wyjaśnić? Bo praktycznie nie rozumiem tematu wątków i w jaki sposób zrobić to zadanie.

0

Jeżeli nie rozumiesz tematu wątków to proponuje sięgnąć do książek lub poszperać w internecie i się nauczyć, bo chyba nie oczekujesz, że ktoś za Ciebie napisze program prawda ?

0

Co do szukania to już dawno to zrobiłem, tylko że słabo jest wyjaśnione na ten temat. A co do kodu to myślałem że chociaż część z tego zostanie wyjaśnione a nie przepisać "żywcem" cały kod.

0

To może z innej beczki. Jak w kodzie można zrobić, żeby wątek obliczał max dla każdej kolumny tablicy (jeżeli mamy do dyspozycji tablicę dwuwymiarową), a potem z obliczonych maxów obliczyć główny max?

0

W klasie, w której mają być odpalane wątki, ustaw jakąś zmienną np. globalMax. Następnie uruchom wątki szukające maxów w swoich kolumnach - najlepiej niech w swojej metodzie run() mają lokalną zmienną max, która jest nadpisywana jeżeli dana liczba z tablicy jest > niż aktualny max. Po czym, niech każdy sprawdza swojego maxa z maxem globalnym globalMax i również nadpisze jeżeli max > globalMax. Neleży tu jednak zadbać o odpowiednią synchronizację.

0

A jak zaimplementować aby ilość wątków była podawana ręcznie w konsoli, a nie ustalona w kodzie? Np. po uruchomieniu podajesz W- ilość wątkow, i w tablicy W-kolumnowej, każdy z wątków będzie przeszukiwał kolejne kolumny. Zrobienie tego w pętli raczej nie wchodzi tu w grę?

0

Czemu nie w pętli ? Wydaje mi się, że zrobienie tego w pętli to chyba najprostsze rozwiązanie. A tak ogólnie, to chyba lepiej by było zrobić to właśnie w kodzie niż dawać użytkownikowi możliwość podania ilości wątków, bo jeżeli użytkownik poda np 20, dla tablicy 10 kolumnowej to 10 wątków będzie tworzonych niepotrzebnie i będzie trzeba dodać jakąś walidację.

0

Zdaje się, że to jest zadanie czysto akademickie, więc nie warto pytać o jego sensowność.
Tablica musiałby być gigantyczna, żeby zauważyć na wielordzeniowej maszynie jakieś przyspieszenie.

Jak to zrobić no to wynika wprost z treści zadania, więc poczytaj o wątkach, podziel tablicę na części i testuj, a nie proś o rozwiązanie zadania domowego.

0
  1. Użytkownik musi podać liczbę wątków, bo to wynika z treści zadania.
  2. Nie proszę o rozwiązanie zadania domowego, bo to nie jest CAŁE zadanie, tylko jego część. Część mam zrobione, ale tej części z dzieleniem tablic i wyliczaniem max z każdej podtablicy po prostu nie mogę zrozumieć, dlatego poprosiłem o wytłumaczenie tego na podstawie implementacji.
1
package Multithreading.Max;

import java.util.ArrayList;


public class FindMax implements  Runnable {
    private static int max;
    private Object lock = new Object();
    private ArrayList<Integer> tab;
    private int start, end;

    public FindMax(ArrayList<Integer> tab, int start, int end) {
        this.tab = tab;
        this.start = start;
        this.end = end;
        max = tab.get(0);
    }

    @Override
    public void run() {
        for(int i = start; i<end; i++) {
            // Synchronizacja - bardzo ważna rzecz
            // gwarantuje że tylko jeden wątek na raz będzie mógł dostać się do maxa
            // jak nie rozumiesz to ją wywal i zobacz co się stanie
            synchronized (lock) {
                if(tab.get(i)>max)
                    max = tab.get(i);
            }
        }
        // pomocnicze wypisywanie podtablic - można wywalić
        System.out.println(tab.subList(start, end));
    }

    public static int getMax() {
        return max;
    }

}

package Multithreading.Max;

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int n, w;
        ArrayList<Integer> tab = new ArrayList<Integer>();
        ArrayList<Thread> threadsTab = new ArrayList<Thread>();
        Random rand = new Random();
        Scanner input = new Scanner(System.in);
        System.out.println("Podaj N");
        n =  input.nextInt();
        System.out.println("Podaj W");
        w = input.nextInt();
        if(n<=0 || w<=0) {
            System.out.println("N i W muszą być dodatnie");
            return;
        }
        else if(n<w)
        {
            System.out.println("N musi byc wieksze od W");
            return;
        }
        // delta - określa ilosc elementów w podtablicy
        // rest - to reszta
        int delta = n / w;
        int rest = n % w;
        // generowanie elementów
        for(int i = 0; i<n; i++)
            tab.add(rand.nextInt(10001));
        // utworzenie W wątków
        for(int i = 0; i<w; i++) {
            if(i + 1 < w)
                threadsTab.add(new Thread(new FindMax(tab, i*delta, delta + (i*delta))));
            else
                threadsTab.add(new Thread(new FindMax(tab, i*delta, delta + (i*delta) + rest)));
        }
        //wystartowanie wątków
        for(Thread t : threadsTab)
            t.start();
        // oczekiwanie na zakończenie wszytkich wątków
        for(Thread t : threadsTab) {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println(tab);
        System.out.println(FindMax.getMax());
    }
}

UWAGA!!! Dzielenie tablicy nie jest optymalne, po prostu daje resztę do ostatniego wątku.

0

Będę musiał jeszcze ten kod trochę przerobić, ale chociaż pozwolił mi zrozumieć ideę tego zadania. Naprawdę wielkie dzięki za poświęcenie mi czasu. Widać, że są chociaż dobrzy ludzie na tym świecie. Dzięki ! :)

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