[ sendai @ 29.09.2007. 14:55 ] @
| Jos jedno pitanje za Java znalce, recimo da imamo kod slican ovome:
Code:
class Proba extends Thread {
public void run() {}
}//:~
public class Tester {
public static void main(String[] args) throws Exception {
System.out.println("BEGIN MAIN");
Proba prvi = new Proba();
Proba drugi = new Proba();
Proba treci = new Proba();
prvi.start();
drugi.start();
treci.start();
System.out.println("END MAIN");
}
}//:~
Ono sto me zanima da li Java garantira pozivanje threadova po redosljedu navodjenja u main() metodi, nije bitno koji ce se prije zavrsiti vec me samo zanima njihovo pokretanje.
Moze li se recimo, ikad desiti da se drugi thread pokrene prije prvog ili treci prije prvog ili drugog?
Dakle hoce li se threadovi APSOLUTNO UVIJEK pokrenuti po redu koji mi naznacimo, bilo da se radi o kompjuteru sa vise procesora ili samo sa jednim?
|
[ lukeguy @ 29.09.2007. 20:43 ] @
Neće.
[ sendai @ 30.09.2007. 14:21 ] @
Ok.Hvala.
[ sendai @ 01.10.2007. 18:33 ] @
Sad imam jos jedno pitanje, a ovo me zanima puno vise nego prvo, pa ako neko zna molim da mi odgovori.
Dakle threadovi se ne pokrecu po redosljedu navodenja, a sta je sa main() metodom, da li ona ima prednost izvrsavanja nad drugim threadovima, dakle (ako ne koristimo join() niti bilo sto drugo) hoce li se apsolutno uvijek prvo izvrsiti main() metoda do kraja, pa tek onda pokretati drugi threadovi?
Sto bi znacilo da u gore datom kodu ispis uvijek treba davati prvo BEGIN MAIN, pa onda
END MAIN i tek onda pokretati druge threadove.
Je li to tako?
[ lukeguy @ 01.10.2007. 23:05 ] @
Vidi ovako. Kada pokreneš Java program, ti time u suštini nalažeš JVM da napravi novu nit (thread) u kojoj će započeti izvršavanje main() metode odgovarajuće klase. Dakle, main() se izvršava u niti (koja je ista kao i bilo koja druga nit).
Onda ti u main() metodi kreiraš nove Thread objekte, tj. kreiraš nove niti i kada pozoveš njihove metode run() te niti se stavljaju u listu spremnih (one niti koje još samo čekaju procesor). Po logici stvari u radu sa nitima (a koja važi i ovde), procesor će biti dodeljen drugoj niti kada prva postane blokirana, kada se prva završi, kada prva to eksplicitno zatraži ili kada istekne kvantum (najduži vremenski period u kojem se može neprekidno izvršavati samo jedna nit). (Mislim da sam pokrio sve uslove.)
Dakle, ovde se ne radi o prioritetima niti, već o tome da je nit u kojem se izvršava main() zapravo nit koja je trenutno aktivna, pa će druge niti dobiti procesor kada se za to ispune uslovi (gore pomenuti). Znači, moguće je da se main() neće uvek završiti do kraja pre nego se pokrene neka druga nit, ali ako u main() metodi samo kreiraš Thread objekte to je zaista malo verovatno.
Suština cele priče je da kod redosleda izvrašavanja niti ništa nije sigurno. Ako ti treba neki pouzdan mehanizam koordinacije niti, onda moraš koristiti neku od metoda koje su za to i predviđene.
[ sendai @ 02.10.2007. 14:58 ] @
Dobro sad mi je jasnije.Samo jos ovo.
Npr. imamo masinu sa vise procesora, ista treba pokrenuti kod u kojoj main ima dosta toga da odradi ali ne pokrece niti jednu drugu nit dok ne dodje npr. do pola.
Ono sto me zanima je da li ce se uvijek prvo desavati da main i odradi do pola, pa tek onda pokrenuti (ili ne) druge niti.Dakle bitna mi je samo ona polovina main metode gdje se ne pokrece ni jedna druga nit, hoce li se to uvijek prvo izvrsavati i na masinama sa jednim procesorom i sa vise njih?
[ Mr. NiceGuy @ 02.10.2007. 20:34 ] @
Mijenjam poruku jer nisam dobro pročitao pitanje.
Uglavnom, ako ti se glavna nit izvodi bez da su ostale pokrenute, program će se (barem do dijela u kojem pokrećeš nove niti) jednako izvoditi na mašinama s jednim ili više procesora (jedna nit se ne može rasporediti na više procesora).
@lukeguy: Mislim da si izostavio thread cancelling, ako to uopće postoji u Javi.
[Ovu poruku je menjao Mr. NiceGuy dana 02.10.2007. u 22:14 GMT+1]
[Ovu poruku je menjao Mr. NiceGuy dana 02.10.2007. u 22:15 GMT+1]
[ lukeguy @ 03.10.2007. 02:06 ] @
Nije mi jasno šta znači da main "ne pokreće niti jednu drugu nit do pola". Ako misliš da se ne kreiraju novi Thread objekti do tada onda da, main se neće prekinuti, jer nema šta da ga prekine. (Main inače i ne pokreće niti, to radi JVM.) U suštini razmišljaj ovako: sve dok ne kreiraš nove niti u tvom programu se sve izvršava redom. Čim kreiraš prvu nit računaj da se od tog trenutka stvari dešavaju paralelno i bez posebnih mehanizama više ne možeš garantovati redosled izvršavanja. Prepuštati stvari slučaju je samo loše programiranje.
[ Jcod3r @ 03.10.2007. 16:21 ] @
Da dobacim, koje su metode za kontrolisanje izvrsavanja niti po redoslijedu ?
[ sendai @ 03.10.2007. 17:24 ] @
lukeguy i Mr. NiceGuy, da to je ono sto me zanimalo.
Pogresno sam se izrazio, mislio sam na kreiranje novih thread objekata u "main()" i njihovog pokretanja sa "start()".
Hvala.
[Ovu poruku je menjao sendai dana 03.10.2007. u 18:48 GMT+1]
[Ovu poruku je menjao sendai dana 03.10.2007. u 18:50 GMT+1]
[ lukeguy @ 03.10.2007. 20:28 ] @
Niti se koriste onda kada je potrebno nešto paralelno procesirati, tako da nema smisla govoriti o njihovom izvršavanju po nekom unapred definisanom redosledu. Ako je potrebno da sinhronizuješ niti (recimo kada niti dele zajednički resurs) Java za to predviđa upotrebu sinhronizovanih metoda i blokova (pogledaj ključnu reč synchronized). A uz pomoć ovog mehanizma možeš implementirati i druge složenije mehanizme sinhronizacije.
[ NeoDesign @ 05.10.2007. 02:23 ] @
a da li bi onda u main metodi mogao da se napravi synchronize blok kojim bi se osiguralo kreiranje sve tri niti po datom redosledu (da se one tri niti kreiraju u takvom bloku)?
[ lukeguy @ 05.10.2007. 21:15 ] @
Ne, to nije funkcija synchronized bloka. On samo omogućava da se pri višestrukom (paralelnom) pozivanju neke metode, deo kôda koji se nalazi u synchronized bloku ne izvršava paralelno (to je u stvari tzv. monitor). Prva nit koja uđe u monitor (krene da izvršava kôd u synchronized bloku) "zaključa" monitor i drži ga zaključanim sve dok ga ne napusti. Kada neka druga nit pokuša da uđe u taj zaključani monitor bude blokirana sve dok prva nit ne izađe iz njega. Ovo koristiš kada želiš da kontrolišeš pristup nekom zajedničkom resursu. Npr. ako više niti piše u jedan isti bafer, ovim mehanizmom obezbeđuješ da niti ne pišu u bafer istovremeno, tj. da ne dođe do prepisivanja i kombinovanja sadržaja iz više različitih niti.
Zbog čega uopšte imaš potrebu da niti pokrećeš po redosledu kad je njihova svrha da se izvršavaju istovremeno?
[ Au197/79 @ 05.10.2007. 22:20 ] @
Da li bi moglo da se sinhronizuju na neki spolji objekat, u smislu da sve niti traže monitor istog objekta (ali samo za početak izvršenja tj. da ga pušte što pre). a da se main nit uzme monitor pre nego što napravi te niti i drži ga dok ne napravi poslednju nit.
[ Mr. NiceGuy @ 05.10.2007. 22:49 ] @
Ako baš želiš da ti se niti izvršavaju po određenom redoslijedu, možeš to učiniti sa semaforima ili uvjetnim varijablama.
Ukoliko želiš koristiti semafore za signalizaciju, napravi po jedan za svaku nit i postavi ga na nulu. Tada svaka nit treba na početku procedure pozvati svoj semafor (i zablokirati), a kada završi s poslom signalizirati semaforu one niti koja se treba sljedeća izvršavati. Naravno, iz jedne niti, npr. glavne, trebaš osloboditi nit koja će se prva izvršavati.
Ako ti nije jasno o čemu govorim, potraži objašnjenje semafora.
[ sendai @ 06.10.2007. 15:47 ] @
Citat: lukeguy:
...
Zbog čega uopšte imaš potrebu da niti pokrećeš po redosledu kad je njihova svrha da se izvršavaju istovremeno?
Ako mene pitas, nemam potrebu nego samo zelim da razumijem kako sve skupa funkcionira.
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|