Avatar billede encorez Nybegynder
03. juni 2013 - 21:44 Der er 17 kommentarer og
1 løsning

Tråde og datadeling

Hej
Jeg har programmeret i PHP tidligere har nu kastet mig over Java.

Jeg skal omprogrammere et "program" fra PHP og har søgt en del på nettet på 2 udestående som jeg håber at få lidt guidance her fra på.

Eksempel: Jeg har en mysql database hvorfra jeg hiver f.eks. 20 MB data ud og gemmer i en fil. Den fil af data, skal jeg eksempelvis løbe igennem 1 million gange, med forskellige variabler, der behandler de data forskelligt.

1. Tråde
For at udnytte alle cpuer på maskinen, vil jeg gerne dele arbejdet med at løbe igennem, de samme data x antal gange, op i tråde.
Det er samme funktion der skal løbe disse data igennem, bare med lidt forskellige parametre hver gang.
Jeg har søgt på nettet, og finde rigtig mange forskellige eksempler og kan ikke gennemskue hvad vil være bedt til dette formål.
Noget input? Og gerne eksempler :)

2. Deling af data
I det nuværende script gemmer jeg disse data i en fil. Den fil indlæser jeg hver eneste gang data skal løbes igennem. Det lyder ikke smart men det var det eneste jeg kunne få til at virke i PHP.
Hvordan vil man gemme eksemplvis 20 MB tekst data, som disse tråde skal indlæse igen og igen?
Forslag? Og meget gerne link til eksempler.

3. Opsamling af resultat
Hver gang én af disse tråde er færdig har den et resultat. Det skal gemmes, sammen med resultatet fra alle de andre tråde.
Når alle tråde er færdige skal alle resultater løbes igennem for at finde den bedste.
Hvordan vil man i Java bedst, nemmest gemme så et resultat fra en tråd for senere at løbe dem alle igennem?

Håber mine spørgsmål er sigende nok, ellers sig endelig

På forhånd mange tak
Avatar billede arne_v Ekspert
03. juni 2013 - 21:50 #1
re 1)

ExecutorService og Future er en glimrende programmerings model for noget som dette.

re 2)

Gem data i memory ikke som fil

re 3)

Future aflverer resultatet paent.
Avatar billede arne_v Ekspert
04. juni 2013 - 02:43 #2
Demo:


import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class MegaJob {
    private static final int NJOB = 1000000;
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService es = Executors.newFixedThreadPool(16);
        @SuppressWarnings("unchecked")
        Future<ParamAndResult>[] workres = new Future[NJOB];
        for(int i = 0; i < workres.length; i++) {
            workres[i] = es.submit(new WorkUnit(new ParamAndResult(i)));
        }
        int maxix = 0;
        int maxres = workres[0].get().getResult();
        for(int i = 1; i < workres.length; i++) {
            if(workres[i].get().getResult() > maxres) {
                maxix = i;
                maxres = workres[i].get().getResult();
            }
        }
        es.shutdown();
        System.out.printf("Max result is %d for param %d\n", workres[maxix].get().getResult(), workres[maxix].get().getParam());
    }
}

class WorkUnit implements Callable<ParamAndResult> {
    private ParamAndResult par;
    public WorkUnit(ParamAndResult par) {
        this.par = par;
    }
    public ParamAndResult call() throws Exception {
        int param = par.getParam();
        // Simulate a lot of work
        Random rng = new Random();
        int res = rng.nextInt(1000000 + param);
        //
        par.setResult(res);
        return par;
    }
}

class ParamAndResult {
    private int param;
    private int result;
    public ParamAndResult(int param) {
        this.param = param;
        this.result = 0;
    }
    public int getParam() {
        return param;
    }
    public int getResult() {
        return result;
    }
    public void setResult(int result) {
        this.result = result;
    }
}
Avatar billede encorez Nybegynder
04. juni 2013 - 21:16 #3
Hej
Det ser meget brugbart ud :) Jeg sidder dog og kæmper en kamp for at forstå hvordan den virker.
NJOB er antallet af tråde right. Men kan man sætte en maks antal tråde der skal kører af gangen? For det er vel ikke smart at starte 1 mio tråde på samme tid?

Her "new ParamAndResult(i)" er hvor jeg kan sende værdier med til tråden som skal lave arbejdet, ikke sandt.
Jeg skal sende 12 tal-værdier med hver gang. Hvordan gør jeg det?
Jeg har forsøgt at modificere den lidt med det lykkes ikke. Skal det være som en String eller i et array?
Avatar billede arne_v Ekspert
04. juni 2013 - 21:41 #4
NJOB er antal job som skal udfoeres. Antal traade er sat til 16.

ParamAndResult kan rettes til at tage et param array eller tage flere params.
Avatar billede encorez Nybegynder
04. juni 2013 - 22:30 #5
Takker, jeg havde ikke set de 16.

Jeg forsøger at rette ParamAndResult til til at tage et array, men jeg misser noget der gør det ikke virker.

Kan du gennemskue hvor jeg mangler at rette?

class WorkUnit implements Callable<ParamAndResult> {
    private ParamAndResult par;
    public WorkUnit(ParamAndResult par) {
        this.par = par;
    }
    public ParamAndResult call() throws Exception {
        int[] param = par.getParam();
        // Simulate a lot of work
       
        System.out.println(param);
        Random rng = new Random();
        int res = rng.nextInt(10 + param);
        //
        par.setResult(res);
        return par;
    }
}

class ParamAndResult {
    private int[] param;
    private int result;
    public ParamAndResult(param) {
        this.param = param;
        this.result = 0;
    }
    public int[] getParam() {
        return param;
    }
    public int getResult() {
        return result;
    }
    public void setResult(int result) {
        this.result = result;
    }
}
Avatar billede encorez Nybegynder
04. juni 2013 - 22:34 #6
Resultatet skal faktisk også være et array kommer jeg lige i tanke om
Avatar billede arne_v Ekspert
05. juni 2013 - 00:25 #7
public ParamAndResult(param) {

compiler vel slet ikke

public ParamAndResult(int[] param) {
Avatar billede encorez Nybegynder
05. juni 2013 - 11:46 #8
Super, det virker som ønsket efter tilretninger rundt omkring.

Har du eksempel på at gemme data i memory én gang, og derefter læsning af disse data fra trådene?

Jeg har søgt og finde ligesom med tråde, masser af forskellige metoder og scripts, og vil gerne som det du har fundet her, have det så enkelt som muligt.
Avatar billede arne_v Ekspert
05. juni 2013 - 21:16 #9
Laes fra fil til en memory struktur.

Send den memory struktur med over i Params.

Forudsat at du kun laeser fra den, saa er det ret simpelt.
Avatar billede encorez Nybegynder
06. juni 2013 - 22:22 #10
Hej. Jeg beklager, men jeg har søgt og søgt og finder igen masser af forskellige muligheder jeg ikke kan gennemskue.
"Laes fra fil til en memory struktur", er der noget helt specielt jeg kan søge på, eller har du et link til noget enkelt og brugbart?
Avatar billede arne_v Ekspert
06. juni 2013 - 22:36 #11
Hvordan er de data du skal analysere gemt?
Avatar billede encorez Nybegynder
06. juni 2013 - 22:54 #12
Det er en komma-separeret fil, med tal-værdier, der skal bruges igen og igen.
Så det hele kunne gemmes som en String i memory, og derefter læse den igennem linie for linie, og split() på komma.
Eller jeg kunne opbygge et array i array, linier og værdier, og gemme selve arrayet i memory.
Hjælper det på hvordan det vil være bedst at gemme det?
Avatar billede arne_v Ekspert
07. juni 2013 - 03:38 #13
Jeg ville lave en klasse med en property per vaerdi i en linie og saa laese ind i en ArrayList af den klasse.
Avatar billede encorez Nybegynder
07. juni 2013 - 19:59 #14
Lyder fornuftigt. Men hvordan gemmer jeg den i memory så den kan læse fra trådene?
Jeg er meget ny i java, så jeg skal enten gerne have metode navnet, et link eller eksempel for at kunne forstå det. Beklager :)
Avatar billede arne_v Ekspert
08. juni 2013 - 23:32 #15
class Data {
    private int a;
    private int b;
    private int c;
    public Data(int a, int b, int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
    public int getB() {
        return b;
    }
    public void setB(int b) {
        this.b = b;
    }
    public int getC() {
        return c;
    }
    public void setC(int c) {
        this.c = c;
    }
}





    public static List<Data> load(Reader rdr) throws IOException {
        List<Data> res = new ArrayList<Data>();
        BufferedReader br = new BufferedReader(rdr);
        String line;
        while((line = br.readLine()) != null) {
            String[] parts = line.split(",");
            int a = Integer.parseInt(parts[0]);
            int b = Integer.parseInt(parts[1]);
            int c = Integer.parseInt(parts[2]);
            res.add(new Data(a, b, c));
        }
        br.close();
        return res;
    }




List<Data> lst = load(new FileReader(fnm));
Avatar billede encorez Nybegynder
08. juli 2013 - 22:24 #16
Hej igen

Har været på ferie, så det er stået stille et stykke tid.

Super, mange tak for hjælpen med eksemplet her på at få data ind i en List og Array og lagt op i memory.

Jeg går ud fra jeg ikke bare kan kopiere dit eksempel ind i en ny Class som den er.

Jeg går ud fra det er forkert som nedenstående, men kan du sige hvordan opsætningen ellers skal være for at eksemplet kan virke.

Læg et svar samtidig. Du har fortjent pointene mange gange som tak for hjælpen :)

public class Data{
  private int a;
  ...
    public static List<Data> load(Reader rdr) throws IOException {
.....
}

List<Data> lst = load(new FileReader(fnm));

}
Avatar billede arne_v Ekspert
09. juli 2013 - 22:22 #17
svar
Avatar billede encorez Nybegynder
11. juli 2013 - 15:49 #18
Tak for hjælpen
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester