[Java lista] szalkezeles
Laszlo.Marai at nokia.com
Laszlo.Marai at nokia.com
2007. Jan. 29., H, 12:52:01 CET
Hali!
> Pár napja emlitettem egy szálkezeléssel kapcsolatos problémát.
> Sajnos azóta sem jutottam elöbb.
Mi meg valaszoltunk is. En biztosan. Es irtam, hogy szinkronizacios
problemarol van szo. Sot, mar hetekkel ezelott megirtuk tobben
is (azota nyuglodsz ugyanis ezzel a kerdessel). Arra is emlekszem,
hogy megneztem neked a Kek konyvben (mert azt hasznalod), hogy 40
oldalt kene elolvasnod, ami nem lehet tobb 3-4 oranal. Ehhez kepest
hetek ota vacakolsz.
Es legyszi probalj mar meg nem HTML levelet kuldeni.
> public class Listaz extends Thread {
Egy apro tanacs: az osztaly nevek fonevek szoktak lenni.
Ha mar ragaszkodunk a magyarhoz, akkor Listazo.
> private boolean futhat;
> public Listaz() {
> futhat = true;
> }
> public void start() {
> if (t == null) {
> t = new Thread(this);
> t.setPriority(Thread.MAX_PRIORITY);
> }
> t.start();
> }
Ez tok rossz. (Gondolom a t a Listaz-ban van definialva, csak
lemaradt a bemasolt kodbol.) Mukodik, meg mukodhetne jol is,
csak nem erted az egeszet. A Listaz foloslegesen szarmazik a Thread-bol
(altalaban erre nincs szukseg, es nem is jo gyakorlat), mert folulcsapod
a start metodusat. Ha a Thread-bol szarmaztatsz, akkor eleg a run
metodust implementalni, az orokolt start metodus elintezi a run
futtatasat. Te azt csinalod, hogy letrehozol egy Thread objektumot
(egy Listaz-t - ugye latszik, hogy fonevnek kene lennie), amiben
letrehozol megegy Thread objektumot. Minek?
> public void run() {
> if (futhat) {
> HashMap hm = itt kap SOAP-on egy HashMap-et
>....
> mystopp();
> }
Ez teljesen rossz. Eloszor is nem olvastad el a Runnable es a Thread
dokumentaciojat. Ha elolvastad volna, akkor tudnad, hogy a run
egyszer fut le. Tehat ha te sokszor akarsz valamit megcsinalni, akkor
a run-ba egy ciklust kell rakni. A te esetedben (mivel gondolom
periodikusan akarod nyomni azt a SOAP request/feltoltest dolot,
egy while ciklust: while( futhat ) {...
Annak, hogy egy metodus igy allitsa le a futasat, nem sok ertelme van.
Most oszinten: a mystopp-ban beallitod a futhat valtozot false-ra. Ki ellenorzi
ezt, es mikor?
> mystopp() {
> futhat = false;
> }
> ez önmagában remekül feltölti a táblát...
Veletlen. Erosen baleset veszelyes kod (egyszer valakinek hozza kell
nyulnia, belenez, es letori a kezed ;) ). A helyes megoldas:
public class Listazo implements Runnable {
private boolean running = true;
public void run() {
while( isRunning() ) {
// Csinaljuk, amit kell
}
}
public synchronized isRunning {
return running;
}
public synchronized void stop() {
running = false;
}
}
Inditasa pedig:
Listazo l = new Listazo(...);
new Thread( l );
Leallitas: l.stop();
Mar ha azt akarod, hogy a Listazo folyamatosan fusson, mert ez
nem derult ki, de gondolom igy van. Hazi feladat, a synchronized
kulcsszo jelentese, es megfejteni, hogy miert van ra szukseg.
> lefutás után (netbeans profilerből is látva) a szál megáll tehát nem fut tehát sikerül megállitani
> profiler is mutatja ...
Nem allitottal meg semmit, veget ert a run metodus, ezert allt le a szal.
Ha csak egyszer akartad futtatni a feladatot (mondjuk azert,
mert GUI-bol inditottad gombnyomasra es nem akartad, hogy lefagyjon
a UI, amig dolgozol), akkor minden "if futhat" buveszkedes nelkul eleg
a run metodust megirni.
Ne felejtsuk el, hogy a kodod ettol meg nem lesz jo, mert nem szinkronizalod
a hozzaferest a tablazathoz (vagy mihez, amibe az adatokat toltod ket szalbol
is). Amig azt nem csinalod meg, nem lesz jo a programod, akkor sem, ha sikerul
egymas utan 100x vagy 1000x a sajat gepeden jol lefuttatnod _veletlenul_.
> CheckTask task = new CheckTask();
> Timer t = new Timer();
> t.schedule(task,1000,10000); //10mp-kent fut!
> a CheckTask-ban 1 SOAP lekeres van szinten..
> public class CheckTask extends TimerTask {
> if (szal == null) {
> szal = new Thread(this);
Ez mar megint minek? Nem fut le 10 mp alatt a keres? Es ha nem, akkor azt akarod, hogy
parhuzamosan elinduljon megegy? Mert ha nem, akkor minek megegy szalat inditani?
> szal.setPriority(Thread.MIN_PRIORITY);
> szal.yield(); //hátha igy elengedi a feltöltő szálat ami eleve nagyobb prioritással bir
Nem csinal semmit a yield, mivel meg nem fut a szalad.
> }
> szal.start();
> }
> public void run() {
> futhat = true; //azert itt true mert a timer ezt hivja meg 10mp-ként és nem a start()-ot
> if (futhat) {
Ennek szerinted oszinten mi ertelme van? Beallitasz egy private valtozot az N. sorban, es utana
megvizsgalod az erteket az N+1-ben. Ki valtoztatta volna meg? Es ha kivulrol (masik
szalbol) meg lehet valtoztatni, akkor miert nem sziknronizalt a hozzaferes? (De
ertelme akkor se nagyon lenne az egesznek.)
Olvasd mar el azt a nyomorult konyvet, vagy legalabb azt a szerencsetlen 40 oldalt!
Abban minden benne van (szalak, parhuzamossag, szinkronizacio). A TimerTask nincs
benne, de mindegy is, mert az nem alapkoncepcio, es ugy am block az egeszet nem erted.
Ha elolvastad, _utana_ kerdezz. Minek irjunk neked konyvet online?
Ba'ly,
Atleta
További információk a(z) Javalist levelezőlistáról