03. juni 2013 - 21:44Der 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
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; } }
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?
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; } }
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.
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?
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?
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 :)
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; }
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.