1 / 31

Programske NITI

Univerzitet mediteran Fakultet za informacione tehnologije. Programske NITI. JAVA PROGRAMIRANjE 2. d ž enan stru jić dzenan@mtel-cg.net Podgorica , 10.11.2008.god. Uvod. Nit je tok naredbi unutar programa , tj . Dio programa u izvodenju .

miles
Download Presentation

Programske NITI

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Univerzitetmediteran Fakultetzainformacionetehnologije Programske NITI JAVA PROGRAMIRANjE 2 dženanstrujić dzenan@mtel-cg.net Podgorica, 10.11.2008.god.

  2. Uvod • Nit je toknaredbiunutarprograma, tj. Dioprograma u izvodenju. • Niti se, za razliku od procesa, izvode unutar kontekstaistogprogramaikoristeresursekoje je alocirao program (varijable, u-i tokove podataka i sl.). • Program možesadržavativišenitikoje se izvode (kvazi)paralelno. Postotakprocesorskogvremenakojicedobiti odredena nit zavisi o prioritetu, koji može primiti vrijednostizmedu MIN_PRIORITY (1) i MAX_PRIORITY(10), a inicijalno je postavljen na NORM_PRIORITY (5).Nacinizvodenjanitizavisi o operativnomsistemu, tj. nacinudodjeleprocesora.

  3. JVM podržava mehanizam dodjele procesora prema fiksnom prioritetu (preemptive round-robin scheduler). Podrška za razdjeljivanje vremena (time slicing) nije ugradena, nego zavisi o operativnom sistemu. • Podrška za višenitni rad ugradena je u definiciju programskog jezika Java. Višenitni rad u ostalim programskim jezicima (npr. C) moguce je realizirati preko sistemskih poziva operatibnog sistema(npr. fork – exec u UNIX-u).

  4. Korištenje niti pruža sljedece prednosti: • Pridonosi interaktivnosti aplikacije. Ako se dugotrajna izracunavanja i obrade obavljaju u posebnoj niti, aplikacija je Idalje u mogucnosti komunicirati s korisnikom. • Omogucuje korisniku paralelno obavljanje više zadataka. Npr. Kod aplikacije za obradu dokumenata korisnik može pokrenutistampanje dijela dokumenta i nastaviti unos teksta. • Ubrzava rad na sistemima s više procesora. Izvodenje pojedinih niti raspodjeljuje se po raspoloživim procesorima, cime se ubrzava izvodenje algoritma.

  5. Stvaranje niti • Pokretanjem Java programa JVM stvara jednu glavnu nit. • Dodatne niti moguce je stvoriti na dva nacina: 1. Nasljedivanjem klase Thread i zamjenom metode run, 2. Implementacijom interfejsa Runnable, koje zahtijeva od klase koja implementira interfejs definisanje metode run. Ukoliko klasa kojom se defenise nit mora naslijediti neku drugu klasu, tada treba koristiti interfejs Runnable. To je slucaj kod definisanja appleta, koji moraju naslijediti klasu Applet

  6. Primjer – nasljedivanjeklase Thread public class PrimjerNiti { public static void main(String[] args) throws Exception { new Nit("Prva").start(); new Nit("Druga").start(); new Nit("Treca").start(); } } class Nit extends Thread{ Nit(String ime) { super(ime); } public void run() { for (int i = 1; i <= 5; i++) { try { sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} System.out.println(this.getName() + ":\t" + i); } } }

  7. Primjer – implementacijainterfejsaRunnable public class PrimjerNiti1 { public static void main(String[] args) throws Exception { new Nit("Prva"); new Nit("Druga"); new Nit("Treca"); } } class Nit implements Runnable{ Thread ovaNit; Nit(String ime) { ovaNit = new Thread(this, ime); ovaNit.start(); } public void run() { for (int i = 1; i <= 5; i++) { try { Thread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} System.out.println(ovaNit.getName() + ":\t" + i); } } }

  8. Rezultatiizvodenja u obaslucajasuslicni: Druga: 1 Treca: 1 Prva: 1 Druga: 2 Prva: 2 Druga: 3 Treca: 2 Prva: 3 Druga: 4 Treca: 3 Prva: 4 Druga: 5 Treca: 4 Treca: 5 Prva: 5

  9. Metode klase Thread • Metode su detaljno opisane u Java API dokumentaciji ... • http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Thread.html

  10. Životni ciklus niti -Nit je u stanju NotRunnable u sljedecim slucajevima: - pozvala je metodu sleep – mora proteci zadani broj milisekundi - pozvala je metodu wait – objekt koji treba ispuniti uslov na koji nit ceka treba metodom notify ili notifyAll dojaviti ispunjenje uslova - ceka završetak u-i operacije – u-i operacija mora završiti

  11. Sinhronizacija niti • Niti se najcešce ne izvršavaju nezavisno, nego rade zajednicki na obavljanju odredenog zadatka. To upraviluzahtijevapristupdijeljenimpodacimailiulaznoizlaznimtokovimapodataka. • Potrebno je osigurati kontrolu nad pristupom dijeljenimpodacima ili u-i tokovima, kako se ne bi desilo da dvije ili višenitiistovremenopristupeodredenimpodacima. Npr. u slucaju baze podataka ili datoteke na disku to moženarušitiintegritetpodataka. • Java implementiraefikasnimehanizamkontrolepristupaodredenomobjektu, metodi, ilidijelukoda: Monitor.

  12. Sinhronizacija niti - prekid • Metoda interrupt omogucuje prekidanje niti koja se nalazi u stanju cekanja. • Sljedeci program šalje prekid niti svake sekunde: public class PrimjerPrekida { public static void main(String[] args) throws Exception { Nit novaNit = new Nit("Nit"); novaNit.start(); for (int i = 0; i < 5; i++) { Thread.sleep(1000); novaNit.interrupt(); } // kontrola preko dijeljene varijable novaNit.kraj = true; } }

  13. class Nit extends Thread { boolean kraj = false; Nit(String ime) { super(ime); } public void run() { while (!kraj) { try { sleep(100); // for (int i=0; i<200000000; i++); } catch (InterruptedException e) { System.out.println(this.getName() + ": stigao prekid !!!"); } } System.out.println(this.getName() + ": kraj."); } }

  14. Nit: stigao prekid !!! Nit: stigao prekid !!! Nit: stigao prekid !!! Nit: stigao prekid !!! Nit: stigao prekid !!! Nit: kraj. Ukoliko nit nije u stanju cekanja, zahtjev za prekid ce biti prihvacen tek kada nit izvrši neku od metoda wait, join ili sleep. Ukoliko je u meduvremenu poslano više zahtjeva za prekid, bice prihvacen samo zadnji.

  15. Sinhronizacija niti - Monitor • Monitor je mehanizam sinhronizacije koji omogucujepristup odredenoj dijeljenoj strukturi (objektu) istovremeno samo jednom procesu ili niti. • Java implementira monitor, koji se postavlja korištenjem kljucne rijeci synchronized • Takva metoda ili dio koda naziva se kriticni odsjecak.. class SinhroniziranaKlasa { public synchronized nekaMetoda(...) { . . . } public nekaDrugaMetoda(...) { . . . synchronized (this) { . . . // sinhronizovani dio koda } }

  16. Primjer public class PrimjerKriticnogOdsjecka { public static void main(String[] args) throws Exception { Semafor sem = new Semafor(); MojThread t1 = new MojThread("1"); MojThread t2 = new MojThread("2"); MojThread t3 = new MojThread("3"); MojThread t4 = new MojThread("4"); t1.start(); t2.start(); t3.start(); t4.start(); } }

  17. class MojThread extends Thread { private int brProc; private StringBuffer suffix = new StringBuffer(); public MojThread(String str) { super(str); brProc = Integer.parseInt(str); for (int i = 1; i < brProc; i++) { suffix.append("\t"); } } public void run() { System.out.println(suffix.toString() + brProc + ". pred kriticnim odsjeckom"); kriticniOdsjecak(brProc, suffix); } synchronized static void kriticniOdsjecak(int brProc, StringBuffer suffix) { System.out.println(suffix.toString() + brProc + ". u kriticnom odsjecku"); try { sleep(2000L); } catch (InterruptedException e) {} System.out.println(suffix.toString() + " |"); System.out.println(suffix.toString() + " |"); System.out.println(suffix.toString() + brProc + ". napušta kriticni odsjecak"); } }

  18. Dio koda kojim je realizovan kriticni odsjecak: class MojThread extends Thread { . . . public void run() { . . . kriticniOdsjecak(brProc, suffix); } synchronized static void kriticniOdsjecak( . . . ) { . . . } }

  19. Sinhronizacija niti: wait - notify • Monitor osiguravajedinstveniinedjeljivipristupodredenomobjektu, ali ne omogucujeuskladivanjeradapojedinihniti. Cestprimjer u kojem se zahtjevauskladivanjeradapojedinihprocesa/niti je "proizvodac– potrošac" (producer-consumer), gdjejedna nit proizvodipodatke, a druga ih koristi. • Metoda wait postavlja nit u red cekanjaodredenogobjektaiprivremenooslobadaobjekt do izlaskaizstanjacekanja. Nit izlaziizstanjacekanjaiulazi u red aktivnihniti (koje se natjecuzaprocesorskovrijeme) u sljedecimslucajevima: • neka druga nit pozove metodu notify ili notifyAll za tajobjekt, • nekadruga nit pošaljezahtjevzaprekid, ili • isteknezadanivremenski interval.

  20. Metoda notify odabire jednu nit iz skupa niti koje cekaju monitor odredenog objekta i stavlja je u red aktivnih niti. • Metoda notifyAll stavlja sve niti koje cekaju monitor odredenog objekta u red aktivnih niti.

  21. Primjer - semafor public class Semafor { private int sem; Semafor() { sem = 1; } Semafor(int s) { sem = s; } public synchronized void waitSem() { while (sem <= 0) { try { wait(); } catch (InterruptedException e) { } } --sem; } public synchronized void sigSem() { ++sem; notifyAll(); } }

  22. public class PrimjerSemafora { public static void main(String[] args) throws Exception { Semafor sem = new Semafor(); MojThread t1 = new MojThread("1", sem); MojThread t2 = new MojThread("2", sem); MojThread t3 = new MojThread("3", sem); MojThread t4 = new MojThread("4", sem); t1.start(); t2.start(); t3.start(); t4.start(); } } Rezultat izvodenja programa je isti (slican) kao u prethodnom primjeru.

  23. class MojThread extends Thread { private Semafor sem; private int brProc; private StringBuffer suffix = new StringBuffer(); public MojThread(String str, Semafor sem) { super(str); this.sem = sem; brProc = Integer.parseInt(str); for (int i = 1; i < brProc; i++) { suffix.append("\t"); } } public void run() { System.out.println(suffix.toString() + brProc + ". pred kriticnim odsjeckom"); sem.waitSem(); System.out.println(suffix.toString() + brProc + ". u kriticnom odsjecku"); try { sleep(2000L); } catch (InterruptedException e) {} System.out.println(suffix.toString() + " |"); System.out.println(suffix.toString() + " |"); System.out.println(suffix.toString() + brProc + ". napušta kriticni odsjecak"); sem.sigSem(); } }

  24. Primjer – proizvodac-potrošac • Program stvara niti Producer i Consumer, te objekt Prodavnica preko kojega proizvodac i potrošac razmjenjuju podatke. public class PrimjerProducerConsumer { public static void main(String[] args) { Prodavnica s = new Prodavnica(); Producer p = new Producer(s); Consumer c = new Consumer(s); p.start(); c.start(); } }

  25. Proizvodac generise deset brojeva u slucajnim vremenskim intervalima trajanja do jedne sekunde. Zadnji generisani broj je nula, što oznacava kraj podataka. class Producer extends Thread { private Prodavnica prodavnica; public Producer(Prodavnica s) { this.prodavnica = s; } public void run() { for (int i = 10; i >= 0; i--) { prodavnica.put(i); System.out.println("Proizvodac postavlja: " + i); try { sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { } } } }

  26. Potrošac prihvaca i ispisuje podatake. Nula oznacava kraj podataka. class Consumer extends Thread { private Prodavnica prodavnica; public Consumer(Prodavnica s) { this.prodavnica = s; } public void run() { int podatak = 0; do { podatak = prodavnica.get(); System.out.println("Potrošac je primio: " + podatak); } while (podatak > 0); System.out.println("KRAJ !!!");

  27. class Prodavnica { private int sadrzaj; private boolean noviPodatak = false; public synchronized int get() { while (noviPodatak == false) { try { wait(); } catch (InterruptedException e) { } } noviPodatak = false; notifyAll(); return sadrzaj; } public synchronized void put(int podatak) { while (noviPodatak == true) { try { wait(); } catch (InterruptedException e) { } } sadrzaj = podatak; noviPodatak = true; notifyAll(); } }

  28. Proizvodac postavlja: 10 Potrošac je primio: 10 Proizvodac postavlja: 9 Potrošac je primio: 9 Proizvodac postavlja: 8 Potrošac je primio: 8 Proizvodac postavlja: 7 Potrošac je primio: 7 Proizvodac postavlja: 6 Potrošac je primio: 6 Proizvodac postavlja: 5 Potrošac je primio: 5 Proizvodac postavlja: 4 Potrošac je primio: 4 Proizvodac postavlja: 3 Potrošac je primio: 3 Proizvodac postavlja: 2 Potrošac je primio: 2 Proizvodac postavlja: 1 Potrošac je primio: 1 Proizvodac postavlja: 0 Potrošac je primio: 0 KRAJ !!!

  29. Klase Timer i TimerTask • Klase Timer iTimerTaskomogucujuizvršavanjeodredenogzadatkanakonistekazadanogvremenskogintervalaili u zadanovrijeme. • potrebno je: • definisatipodklasuklaseTimerTaskcijametoda run() sadržikod koji obavlja traženi zadatak, • stvoriti nit stvaranjem instance klase Timer, • stvoritiinstancudefinisanepotklaseklaseTimerTask, • rasporediti nit zaizvodenje. • U sljedecem primjeru zadatak se rasporeduje zaperiodickoizvodenjesvakedvijesekunde. Nakon pet izvodenja zadatak se više ne rasporeduje.

  30. import java.util.Timer; import java.util.TimerTask; public class PrimjerTimera { Timer timer; public static int brojPoziva = 1; public PrimjerTimera(int sekunde) { timer = new Timer(); timer.schedule(new NitTimera(), sekunde*1000, sekunde*1000); } class NitTimera extends TimerTask { public void run() { System.out.println("\tZadano vrijeme isteklo " + brojPoziva + ". puta"); if (brojPoziva++ == 5) { timer.cancel(); } } } public static void main(String args[]) { System.out.println("Rasporedivanje niti timera:"); new PrimjerTimera(2); System.out.println("Nit rasporedena ..."); } }

  31. Metoda schedule održava tacno vrijeme izmedu dva uzastopna izvršenja niti. Ako se traži vremenska tacnost u duljem periodu, treba koristiti metodu scheduleAtFixedRate. Rasporedivanje niti timera: Nit rasporedena ... Zadano vrijeme isteklo 1. puta Zadano vrijeme isteklo 2. puta Zadano vrijeme isteklo 3. puta Zadano vrijeme isteklo 4. puta Zadano vrijeme isteklo 5. puta

More Related