Multithreading i java

Tags:    java mulitithreading

Hej alle,

Jeg er stadig meget interesseret i at få hjælp til kodningen af en flertrådede applikation i java.

Så det ser ud lige nu har jeg forsøgt at få det lavet siden i søndags og det er ikke lykkedes mig at komme frem til noget som helst brugbart. Jeg er ikke en gang kommet i nærheden af et resultat.

Så er der nogle derude som har lyst til at guide mig eller give mig noget konkret kode jeg kan prøve at bygge videre på?

Opgaven er som sagt at udregne primtal vha. flertrådet programmering i Java.

kærlig hilsen

Emilie



7 svar postet i denne tråd vises herunder
1 indlæg har modtaget i alt 6 karma
Sorter efter stemmer Sorter efter dato
Her er der et lidt grimt forsøg:
Fold kodeboks ind/udJava kode 


Hver Callable objekt tester 1000 tal og returnerer en liste af dem, som er primtal. Jeg smider en masse af disse callables efter en threadpool, og for hver callable får jeg et Future objekt retur.

Disse Future objekter smider jeg i en liste i den rækkefølge, de oprettes i. Efterfølgende venter jeg på, at den første bliver færdig og udskriver dens resultat. Derefter fortsætter jeg med den næste, og bliver ved på den måde, til alle opgaverne er løst.

Det kan nok gøres kønnere, men det må du selv klare...håber det er til at gennemskue.



Indlæg senest redigeret d. 09.02.2013 00:19 af Bruger #2695
Her er der et lidt grimt forsøg:
Fold kodeboks ind/udJava kode 


Hver Callable objekt tester 1000 tal og returnerer en liste af dem, som er primtal. Jeg smider en masse af disse callables efter en threadpool, og for hver callable får jeg et Future objekt retur.

Disse Future objekter smider jeg i en liste i den rækkefølge, de oprettes i. Efterfølgende venter jeg på, at den første bliver færdig og udskriver dens resultat. Derefter fortsætter jeg med den næste, og bliver ved på den måde, til alle opgaverne er løst.

Det kan nok gøres kønnere, men det må du selv klare...håber det er til at gennemskue.


Hej,

tak for hjælpen først og fremmest - jeg påskønner virkelig din tid og insats - hvor er det dejligt at hjemmesider som udvikleren.dk kan hjælpe mig til at forstå java.

Jeg har dog et par spørgsmål til din kode som jeg håber du kan hjælpe mig med at klargøre.

Hvad mener du med gøres kønnere? Med henblik på hvilken del af koden?

Koden virker fint når jeg compiler i netbeans, men jeg har stadig nogle spørgsmål til de enkelte dele af koden og derfor ville det være en stor hjælp hvis du kunne lave nogle kommentarer til mig i de kodestykker jeg har fremhævet.

Kravet til opgaven er at implementere thread-klassen eller at implementere runnable interfacen.

Derudover kan vi implementere runnable-interfacen og bruger run-metoden. Jeg har læst mig frem til at runnable er et supplement til callable så har du mulighed for at lave dette om i koden således at du bruger runnable og indfører run-metoden i stedet for callable og call-metoden??

Endnu en gang stor tak for hjælpen

Vh Emilie


/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package threading;

/**
*
* @author emiliebalslev
*/
class MyRunnable implements Runnable{
private int a;

public MyRunnable(int a){
this.a = a;
}

@Override
public void run(){
for (int i = 1; i <= a; ++i){
System.out.println(Thread.currentThread().getName() + " is " + i);
try{
Thread.sleep(1000);
}
catch (InterruptedException e){}
}
}
}

class MaiMyThread{
public static void main(String args[]){
MyRunnable thr1, thr2;
thr1 = new MyRunnable(5);
thr2 = new MyRunnable(10);
Thread t1 = new Thread(thr1);
Thread t2 = new Thread(thr2);
t1.start();
t2.start();
}
}
(det er i dette format jeg ønsker min flertrådede applikation skal være)



Indlæg senest redigeret d. 09.02.2013 21:24 af Bruger #16850
Jeg kalder min løsning for "grim" fordi, den bruger "magiske" konstanter, ikke tilbyder et pænt og brugbart API, og fordi den er for kompakt (efter min mening). Det er ret subjektive målepunkter, så ikke alle ville være helt enige. However, det var bare for at illustrere brugen af thread pools og callables, så med det i mente, så mener jeg, at løsningen var god nok.

Hvis vi giver dig den fulde løsning (den du selv bad om), så gør vi dig en bjørnetjeneste, for det er en skoleopgave, og det er meningen, at du skal svede over den selv...hvis du gør det, så får du meget ud af arbejdet, uanset om du ender med en brugbar løsning. Nogle af mine bedste og mest lærerige timer gik på at lave fejl på fejl på fejl, så jeg vil stærkt opfordre dig til at slide videre selv...tråd programmering ér svært!

Men her er et par pointere.

Lad være med at tænke på opgaven som kode. Det er ikke tråde, men mennesker, som du skal sætte i arbejde. Du selv tager opgaven som "hovedtråden". Du har fire kammerater, som er dine "arbejdertråde".
Dine fire kammerater står ved et transportbånd (en java.util.concurrent.BlockingQueue), hvor du (hovedtråden) lægger opgaver (queue.put(new Assignment())). Dine kammerater tager så opgaver fra transportbåndet (queue.take()), og arbejder på dem.

Når du har lagt disse opgaver på transportbåndet, så går du hen til kassen (endnu en java.util.concurrent.BlockingQueue), hvor dine kammerater lægger resultatet af deres arbejde. Du tager så deres resultater, efterhånden som de dukker op (de kommer sandsynligvis ikke i rigtig rækkefølge), og efterprocesserer dem (lægger dem i rækkefølge og skriver dem ud).

Alle dine kammerater udfører samme type opgave, så deres instruktion kan nedfældes i en klasse, som implementerer Runnable.

Så det du skal bruge er to instanser af BlockingQueue, en klasse som implementerer Runnable, og som kan tage opgaver fra én BlockingQueue. Opgaven skal indeholde informationer om, hvilke tal, som skal testes for om de er primtal (first og last). Resultatet kan være en List<Long> som så smides i den anden BlockingQueue.

Der er mange måder at løse opgaven på, men hvis du tænker i analogier som den ovenstående, så kan du meget lettere visualisere en løsning. Sådan gør jeg selv konstant.

Håber det fik dig lidt videre, ellers så spørg til noget konkret...ikke "giv mig en fuld løsning".



Jeg forstår godt din analog, men jeg er i tvivl omkring hvordan jeg opretter denne liste af resultater.


Skal jeg deklarere et felt med en variable som tager datatypen "Long" og så indsætte specifikke værdier som er alle primtal fra f.eks. 0-1000 på forhånd når jeg instantierer feltet i en konstruktor?



Du kan gøre ca. som i den løsning, jeg postede. Et objekt med en range, og så er resultatet en liste af Long objekter, som alle er primtal.

Altså noget i stil med:
Fold kodeboks ind/udJava kode 


Din hovedtråd kan instantiere en række objekter af ovenstående klasse og give dem til et par tråde, som kan tygge på dem.
Derefter kan hovedtråden så hente løsningen ud af hvert objekt og udskrive resultatet.



Indlæg senest redigeret d. 11.02.2013 22:41 af Bruger #2695
Okay vil du uddybe hvordan jeg skal bygge min hovedtråd op så den kan instantiere disse objekter?
Skal jeg oprette en klasse som extends fra Thread-klassen hvori jeg opretter en række objekter med tråde?


/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package threading;

/**
*
* @author emiliebalslev
*/
class MyRunnable implements Runnable{
private int a;

public MyRunnable(int a){
this.a = a;
}

@Override
public void run(){
for (int i = 1; i <= a; ++i){
System.out.println(Thread.currentThread().getName() + " is " + i);
try{
Thread.sleep(1000);
}
catch (InterruptedException e){}
}
}
}

class MyThreads{
public static void main(String args[]){
MyRunnable thr1, thr2;
thr1 = new MyRunnable(5);
thr2 = new MyRunnable(10);
Thread t1 = new Thread(thr1);
Thread t2 = new Thread(thr2);
t1.start();
t2.start();
}
}


På den samme måde som i dette eksempel, men hvor jeg indsætter felterne "first", "to" og "result" på samme måde som jeg har indsat feltet a?

Jeg er også i tvivl om hvordan jeg kan lave hente listen ind i min run-metode på samme måde som du har gjort i den call-metode. Problemet er jo nemlig at list<Long> ikke er brugbare med et void-return statement



Indlæg senest redigeret d. 11.02.2013 23:51 af Bruger #16850
Tjoeh tjah...jeg ved ikke hvad 'a' repræsenter i din kode, men alle tråde er sat til at løbe fra 1 til 'a'. Jeg tror, at 'a' er hvad jeg kalder 'to' i min 'Assignment' klasse, men du har ikke en 'first', som er det første tal, som skal testes for om det er et primtal. Bare smid det med som parameter til MyRunnable klassens constructor.

Runnable kan ikke returnere noget, så den er nødt til at generere et resultat, som det kan levere til hovedtråden, måske via en liste...eller man kan gøre noget lidt andet :-)

Hvis du kigger i min Assignment klasse, så har jeg lagt op til en anden løsning. Der er en 'solve()' metode og en 'getSolution()' metode. De er begge synchronized. 'getSolution()' skal tjekke, om løsningen foreligger, og hvis den gør, så bare returnere den. Hvis ikke, så skal den vente (Object.wait()) på, at løsningen bliver lavet.

'solve()' metoden laver så løsningen, og når den er færdig, så fortæller den det til alle interesserede (Object.notifyAll()).

De er ikke implementerede, men det kan du selv gøre, hvis du vil gå efter den løsning.

Hovedtråden kan lave en række af disse Assignment objekter og ligge hver i en liste, som den selv kan iterere over senere. De bliver også lagt i en kø, som et par arbejder tråde kan tømme.

Tror det er det nemmeste, hvis man absolut skal bruge Runnable :-)



Indlæg senest redigeret d. 12.02.2013 09:54 af Bruger #2695
t