You are on page 1of 16

IR3KDP Laboratorijska Veba 2

Youtube transkript

CONCURRENT PROGRAM

LAB VEBA 1 i 2: REAVANJE PROBLEMA KONKURETNE APLIKACIJE Znai proli put smo imali aplikaciju koja treba da bude poetak distribuirane aplikacije. Ta aplikacija je bila vrlo jednostavna sastojala se iz jednog potanskog sandueta, a eleli smo da napravimo sloj apstrakcije. Kako bi radilo to potansko sandue !? pa tako to ono prima poruke koje moe da zadri neko vreme, ukoliko se ne isporue korisniku u odgovarajue vreme te poruke se eliminiu iz potanskog sandueta. Ali u naoj prvoj verziji MessageBox-a koju realizujemo, mi smo eliminisali taj period vremena i u sutini ono se ponaalo kao Bounded Buffer. Ideja kod Lab2 vebe je da ovo to imamo na neki nain moemo da koristimo vienamenski. Ideja je MessageBox moe da se koristi bez obzira da li se transportuje Textualne Poruke ili Informacije o Simulatoru Diskretnih Dogaaja ili Obradi slike. Znai MessageBox prima neki tip poruke i mi ubacujemo tu poruku u MessageBox. to se MessageBox-a tie ono nekako treba da transportuje te Poruke i sandue ne bi trebalo da bude upoznato sa tim ta je sadraj Poruke. GUI aplikacije je jednostavan s jedne strane GUI treba da ita TextField, zatim da kreira novu Poruku i da je ubacuje u MessageBox. Ona druga strana GUI-a treba da ita Poruku iz MessageBox-a kada pritisnete Button i da tu poruku ispisuje u TextField-u. Ideja je da ova naa aplikacija ne bude svesna DA LI JE MessageBox NA JEDNOM(lokalnom) RAUNARU ili NA UDALJENOM RAUNARU. Praviemo DISTRIBUIRANU VERZIJU OVE NAE APLIKACIJE koja e zameniti postojeu implementaciju aplikacije(sa Lab1 vebi) gde smo imali DELJENU LOKALNU PROMENLJIVU , sa promenljivom koja e se NALAZITI NA SERVERU, znai MessageBox e se nalaziti na serveru. Mi emo MORATI DA NAPRAVIMO PROTOKOL kako e SERVERSKA i KLIJ ENTSKA strana MessageBox-a DA KOMUNICIRAJU znai implementacija SERVER-CLIENT PROTOKOL KOMUNIKACIJE. Na Lab4 vebi emo ovu aplikaciju proiriti tako da MessageBox bude realizovano koristei RMI u java prog.jeziku. Da se sada setimo ta nam to proli put nije radilo ukoliko pritisnemo na dugme Get naa Nit GUI-a ode do buffera (MessageBox-a) i zablokira se. To ne valja razlog zato to ne valja je GUI se izvrava u SAMO JEDNOJ Niti. To emo uskoro da vidimo ali videemo i koliko iznosi broj Niti i malo emo da se etamo kroz konkuretno izvravanje videemo kako se koristi debuger u Eclipse-u. Uzmite sada va code sa Lab1 vebe u diirektorijumu Materijali i iskopirajte ga negde moe na Desktop ili u direktorijum Rad(najbolje u Rad jer e tu uvek ostati code za sledeu nadogradnju na predstojeim Lab vebama). Na dva naina moe ubaciti code sa Lab1 direktorijuma jedan je da kreirate New Project i da kaete Build (ili Import) From Existing Source (tj kada digne Eclipse, desni klik miem i onda Import->General->Existing Project Into Workspace, klikne Next button). Ima u File meniju Import i Export opcije tako da to moete da odaberete.

Strana 1 od 16

IR3KDP Laboratorijska Veba 2

Youtube transkript

CONCURRENT PROGRAM

Slika 1

Slika2

Ako se sluajno desi da Java Compiler ne zna gde je main funkcija koju treba d a pokrene uradi sledee u package exploreru klikni desni klik i otvorie se meni na slici 2, odaberi Run Configuration.

Strana 2 od 16

IR3KDP Laboratorijska Veba 2

Youtube transkript

CONCURRENT PROGRAM

Ajde sada da jurimo greke u konkuretnom programu ! Ako kliknemo dugme Put da li e da radi aplikacija!? Kada ukucamo neki text i kliknemo Put, aplikacija RADI, ali kada probamo Get dugme da kliknemo APLIKACIJA ZABLOKIRA. Ajde da vidimo koliko Niti uopte postoji u naoj aplikaciji. Kako to!? Pa tako to emo pokrenuti aplikaciju u Debug mode-u (ajde da vidimo kako se ide korak po korak u naoj aplikaciji). Znai nas zanima da vidimo ta se dogaa kada neko pritisne dugme Get i aktivira se metoda actionPerformed(ActionEvent). Tako da morate u toj taki liniji koda gde se nalazi odgovarajua metoda da stavite BREAKPOINT tako to dvaput kliknete na toj liniji. U gornjem desnom prozoru Debug moete videti koliko vaa aplikacija ima Niti i vidimo da naa ima 4 niti. ta

1 2 3 4

Nit oznaena kao 4, DestroyJavaVm je naa main Nit. Nit oznaena kao 3, AWT -EventQueue je Nit koja radi OBRADU DOGAAJA. ta je to obrada dogaaja!? Sve ovo kada svaki put kliknete, kada preete miem iznad neega POKREE SE OBRADA DOGAAJA i pita se da li postoji neka klasa, neki Listener, koja treba da radi obradu dogaaja. Ove dve gornje Niti, oznaene kao 1 i 2 se odnose na rad GUI-a. A zato se je ovaj EventQueue AWT-EventQueue kada smo rekli da je AWT malo zastareo!? Nije AWT zastareo kao skup biblioteka, nego AWT komponente rade sporo iscrtavanje, nisu dovoljno brze, nisu lepe i velike su. Ali su sve drugeklaseleppo napisane u AWT paketu pa i ove klase Listener i za obradu dogaaja, a nama upravo EventQueue radi obradu dogaaja.

Strana 3 od 16

IR3KDP Laboratorijska Veba 2

Youtube transkript

CONCURRENT PROGRAM

Da biste videli ta se sve izvrava na maini u okviru Niti sve do ovog naeg GUI Prozora za Put ekspandirajte Thread[AWT-EventQueue]:

Ovde ima nekoliko desetina poziva a poinjemo odozgo, znai poziva se neki Dispatcher koji se vrti u nekoj petlji i eka da se desi neki dogaaj, sve dok nismo doli do Button -a i poziva actionPerformed(). E sada moemo da gledamo vrednosti nekih promenljivih. U Gornjem desnom delu ekrana vam se prikazuju sve promenljive koje su vidljive do ovog trenutka. ta radi podrazumevano metoda toString() svakog objekta !? vraa puno ime KLASE pa majmunsko a tj @ i onda code ovog vaeg objekta da biste na jedinstven nain identifikovali objekat.

Strana 4 od 16

IR3KDP Laboratorijska Veba 2

Youtube transkript

CONCURRENT PROGRAM

Nas zanima buffer polje koje je tipa LinkedList<T> to znai da smo buffer implementirali kao ulanana lista i nas tu najvie zanima polje SIZE te liste vidimo da je ono NULA. To znai da nita nismo ni stavili u buffer, on je prazan, tako da Nit ovde nee ekati tj moe da stavi Objekat u MessageBox tj u LinkedList<Message<String>>.

Znai poto je ispunjen uslov za Put idemo na funkciju buffer.add(Message<String>):

Moete videti src code implementaciju jave u java programskom jeziku (C:\Program Files (x86)\Java\jdk1.7.0 ) ali za sve operacijekoje zahtevaju systemsku uslugu OS-a to nije dostupno kao open source jer je zatieno patentom i pisano je u C prog.jeziku (kao npr rad sa File-ovima java mora da izae iz JVM okruenja i da pozove OS uslugu takoe i rad sa IO...).
Strana 5 od 16

IR3KDP Laboratorijska Veba 2

Youtube transkript

CONCURRENT PROGRAM

ta je PROBLEM zato se naa Nit blokira !? Znai imamo jednu Nit GUI-a. Kada neko pritisne GUI dugmence, i kae Get, ta naa jedina Nit se zablokira. Mi elimo da napravimo reenje da se naa jedna Nit ne zablokira kako moemo da NAPRAVIMO NOVU NIT I DA SE NAA NOVA NIT ZABLOKIRA, A DA SE NE ZABLOKIRA NIT GUI-a !??? Kako se kreira Nit !? Koja dva naina !? Imlementiranjem interfejsa Runnable ili klasa Thread. Mi emo ovde da kreiramo instancu klase Thread. Znai napraviemo jo jednu unutranju klasu isto da vidimo kako se imenuje jo jedna unutranja klasa. I ubaciemo sav code u telo te nae Niti: public Put() { .... button.addActionListener( new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { Thread t = new Thread(){ public void run(){ Message<String> m=new TextMessage(); m.setBody(area.getText()); buffer.put(m, null, 0); } }; t.start(); }

} ); .... } KORISTITI ctrl+shift+F ZA FORMATIRANJE CODE U ECLIPSE OKRUENJU. Ako pogledate ta smo sada napravili mi smo kreirali Novu Nit UNUTAR POZIVA kada kliknemo button Get poziva se actionPerformed(ActionEvent) metoda koja kreira Novu Nit, koja treba da napravi Message, da uzme iz TextField-a text i kreira body Message-a na osnovu toga a na samom kraju da stavi Message object u MessageBox. Vidimo da smo napravili Novu nit koja je unutranja klasa unutranje klase ActionListener. Koji naziv ima unutranja klasa ove unutranje klase !? Znai nalazi mo se trenutno u klasi Put, i trenutno smo u unutranjoj klasi ActionListener koja je u Put klasi pa e se ActionListener anonimni objekat zvati Put$1. Zatim e se unutranja klasa Thread koja se nalazi u unutranjoj klasi ActionListener zvati Put$1$1. (to sve moe proveriti ako ode u folder project tj u na projekat na C:\.. disku).

Strana 6 od 16

IR3KDP Laboratorijska Veba 2

Youtube transkript

CONCURRENT PROGRAM

Obavezno prati ID objecata npr sada ima MessageBox buffer sa ID = 1373, a onaj od malo pre jebio buffer sa ID = 1395. ta ne valja ovde!? IMAMO DELJENU PROMENLJIVU ILI OBJEKAT u ovom sluaju je to buffer, ali ga nismo zatitili tj nae dve Niti rade svaka sa svojim bufferom a ne sa jednim erovanim bufferom. Znai nama u klasi Put i Get NE VALJA KREIRANJE BUFFERA. Ono to treba da uradimo je da u konstruktorima klasa Put i Get da prosledimo na buffer s kojima rade tj koje ove dve Niti treba da eruju. Kada smo reili problem sa erovanjem buffera i promenili konstruktor klasa Put i Get i pokrenuli aplikaciju ona je radila ali ne ba onako kako mi to elimo jer ubacili smo prvi Message i ona je uspeno dohvaena ali kada ubacimo drugiMessage ona se ne dohvata, znai samo prvi Message dohvati a ostale nee. PROBLEM 2: UBACILI SMO 2 Message objekta qwertz i qwerty ali smo uspeli samo da dohvatimo prvi string qwertz. TO NE VALJA. POKRENI DEBUGER: Obrati panju kada posle put ue u get metodu nee se zablokirati nit jer u bufferu postoji jedan string, otiiemo na buffer.get(0) pa na lock.unlock() i TADA OBRATI PANJU NA TO KOLIKO JE STRINGOVA OSTALO U BUFFERU. VIDEE NEPRAVILNO STANJE BUFFERA broj stringova je jedan. To znai mi smo pokupili element iz buffera ali on je ostao u bufferu. To nismo hteli da uradimo. Mi HOEMO DA DOHVATIMO ELEMENT I DA GA IZBACIMO IZ LISTE. Get() metoda je samo vraala referencu na element ali ga nije izbacivala iz liste. ZATO UMESTO get() EMO POZIVATI buffer.remove(0), koji ode na poziciju 0 u listi i vrati element i izbacuje ga iz liste. TE PROMENE RADI U KLASI ListMessageBox. PROBLEM 3: Get klasa NE DOHVATI BA SVAKI PUT KADA STISNEM DUGME ve neto kasnije ZATO!? Naa Nit se zablokira i eka ako je buffer pun kadaradi put() to je znai OK. ALI NAE METODE put() i get() u klasi ListMessageBox: public void put(Message<T> m, Prioritet prioritet, long ttl) i public Message<T> get(long ttd, Status status) NE VALJAJU. FALI TI SIGNALIZIRANJE . Signal() se radi tako to kada se signalizira nit ona ne dobija Lock po buenju nego ide u Entry Queue Lock objekta i eka svoje exluzivno pravo na bravu kada se gubi exluzivno pravo: kada uradimo lock.await() i kada uradimo lock.unlock(). Iz gore navedenog razloga NIJE NAM BITNO DA LI full.signal() u metodi put() klase ListMessageBox dolazi pre ili posle buffer.add(message) jer mi svakako nemamo Lock kada se Nit probudi. Analogno vai i za get() metodu uklasi ListMessageBox PROBLEM 4: elimo korisniku da isporuimo poruke u ONOM REDOSLEDU KAKO SU KREIRANE. Npr ako imate buffer veliine 2 a vi ste kreirali 10 Niti koje stavljaju neto 2 Niti se neeblokirati ALI OVIH 8 e se blokirati jer je buffer pun. Ali sad je pitanje kojim redosledom e se buditi te Niti to zavisi od Schedulera. Moramo smisliti jednostavan nain danam to buenje ne zavisi od Schedulera. Zamisli da pie poruku ili pismo a da se smetaju shar poshar te p oruke bounded buffer a poruka bi bila nejasna ako bi randomly pristizalo. Ne treba ti ovde neki tamo ticket algoritam koji e da sihronizuje gomilu Niti. UVEK REAVAJ TO TO JE PROBLEM pitaj se uvek ta bee ne radi i ta to bee mi reavamo, koji je to problem koji reavamo ralanite ga i reite ovde je problem ako se napuni buffer trebamo na neki nain da NEALJEMO VIE PORUKA. Ovde nemamo REFERENCE NA NITI KOJE SE TRENUTNO IZVRAVAJU. Znai ne znamo ni kako bismo mogli konkretnu nit da imanujemo jer mi ovu nau Nit ()imamo kao unutranju klasu koju smo pokrenuli i zaboravili na nju znai mi nemamonigde referencu na ovo nae t tj na tu Nit. Znai nemamo referencu na ovu nau Nit t (ova
Strana 7 od 16

IR3KDP Laboratorijska Veba 2

Youtube transkript

CONCURRENT PROGRAM

lokalna Thread t = new Thread()) jer ona negde nestaje u klasi kao da smo zaboravili na nju posle njenog pokretanja. Zbog toga neemo da idemo na tu stranu sreenjem,nego emo da uradimo vrlo jednostavnu stvar. AKO BI SE ZABLOKIRALA NAA Nit PRILIKOM UBACIVANJA NEEGA U BUFFER DA LI BI TO ZABLOKIRALO NAU Nit GUI-a !? ODGOVOR JE NE. DA LI MOEMO DA ZABLOKIRAMO NEKAKO KORISNIKA KOJI TREBA NETO DA UBACUJE ILI DA DOHVATA IZ BUFFERA A DA NE ZABLOKIRAMO ONAJ DEO KOJI NETO DOHVATA IZ BUFFERA KADA KAEMO KORISNIKA, MISLIMO NA APLIKACIJU CEO TAJ JEDAN DEO APLIKACIJE !? NAJEDNOSTVANIJE KAKO MOEMO DA JE ZABLOKIRAMO JE DA ONEMOGUIMO ONO DUGME KOJE KORISNIK MOE DA PRITISNE. Znai vi trebate KORISNIKU da ZABRANITE DA UBACUJE u buffer kada je BUFFER PUN. Znai ako je BUFFER NAPUNJEN, a pri tom postoji jedna Nit koja hoe da ubacuje, mi je zablokiramo-zabranimo joj da ubacuje-i to e biti jedina Nit koja e da saeka na bufferu da se isprazni i samim tim ONA E BITI JEDINA KOJA E BITI PROBUENA SLEDEA jer neemo kreirati ni jednu sledeu Nit posle nje. MI SAMO TREBA DA ZABRANIMO BUTTON KORISNIKU KADA JE BUFFER PUN. To button.setEnabled(false) trebamo da uradimo pre nego to se naa Nit zablokira i nakon zavretka te nae Niti moramo da odblokiramo to dugme sa button.setEnable(true) da bi korisnik znao da imamesta u bufferu.. Koda je to pre kreiranja nae Niti zablokiraj Button korisniku ako je buffer pun !? To je SIGURNO PRE KREIRANJA NAE ANONIMNE Niti. Pre code: .***modification***..Thread t = new Thread() { public void run() { ...} ...}... Kada je to posle zavretka Niti !? Posle Code: t.start(). public class Put extends JFrame { ..... button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { button.setEnabled(false); Thread t = new Thread() { public void run() { Message<String> m = new TextMessage(); m.setBody(area.getText()); buffer.put(m, null, 0); } }; t.start(); button.setEnabled(true); } }); ..... }} //class Put To isto analogno uradi i u klasi Get. PROBLEM 5:
Kada pokrenemo aplikaciju naii emo na problem: nama je buffer veliine 2, ali ispalo je da moemo da ubacujemo koliko hoemo ne blokira se button to ne valja to ne elimo da radi naa aplikacija. Ajde da debugujemo sada da vidimo koliko imamo Niti. Vidimo da je ovde problem to smo rekli da se dugme blokira dok se PRVA Nit ne zavri ali mi i dalje imamo Druge Niti koje se kreiraju i posle te zabrane tj posle setEditable(false)
Strana 8 od 16

IR3KDP Laboratorijska Veba 2

Youtube transkript

CONCURRENT PROGRAM

Znai problem je to smo stavili button.setEnabled(true); posle t.start() poziva tu ne treba da sotoji button.setEnabled(true);Znai kada proemo kroz debugging videemo sledee: zabranimo dugme, kreiramo Nit, zatim startujemo Nit, saekamo da se zavri start() i pozovemo odblokiraj dugme - ZNAI TREBALO BI DA BUDE NA KRAJU run() METODE, a ne na kraju start() metode. Znai ako stavimo button.setEnabled(true); posle poziva start() TO NIJE NAKON ZAVRETKA NITI to su dve razliite stvari (misli na zavretak metode start() i zavretak Niti). Vi ste ustvari sa ovim kodom: ... t.start(); button.setEnabled(true);... rekli NAKON TO ZAPONE NIT DEBLOKIRAJ DUGME. TREBA STAVITI button.setEnabled(true); u metodi run() odgovarajue Niti tanije NA KRAJU run() metode. // class Put button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { button.setEnabled(false); Thread t = new Thread() { public void run() { Message<String> m = new TextMessage(); m.setBody(area.getText()); buffer.put(m, null, 0); button.setEnabled(true); } }; t.start(); //button.setEnabled(true); } }); // class Get button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { button.setEnabled(false); Thread t = new Thread() { public void run() { Message<String> m = buffer.get(0, null); area.setText(m.getBody()); button.setEnabled(true); } }; /** ako ovde umesto t.start() stavimo t.run() * poziv nee biti ispravan jer kada tako pozove * ti ne kreira nit nego obian objekat. * Znai nismo napravili Nit na taj nain ! */ t.start(); //button.setEnabled(true); } });

Strana 9 od 16

IR3KDP Laboratorijska Veba 2

Youtube transkript

CONCURRENT PROGRAM

E sada e raditi kako treba: ubaci prvi Message, ubaci drugi Message, kada pokuamo(kliknemo dugme put) da ubacimo i trei Message, NAM SE ZABLOKIRA DUGME. Kada imate u vaem konkuretnom programu priam sada vizuelno tj kada vidite u vaem programu da imate Condition.await(); obavezno morateda imate Condition.signal(); ta je par za wait() metodu u bloku synchronized(Object){... wait(); ...} !? Naravno notify() ili notifyAll(). Seti se da svi objekti u Javi - su tipa Object koji imaju metode wait() i notify() ili notifyAll(), ali uslov da biste pozivali ove metode - MORATE BITI UNUTAR synchronized bloka nad promenljivom tipa Object. Ako ne pozovete ove metode unutar synchronized bloka onda se baca izuzetak tipa IllegalMonitorStateException. Locks i Semaphores nisu isto. U klasi java.utill.concurrent.Semaphore imate acquire() koja radi sledee: Acquires a permit from this semaphore, blocking until one is available, or the thread is interrupted. I imate release() koja radi sledee: Releases a permit, returning it to the semaphore.. Sada emo da vam

postavimo zadatak

koji trebate samostalno da radite: trebate da

napravite DVE IMPLEMENTACIJE BUFFER-a: jedna implementacija treba da bude sa nizovima i kljunu re synchronized a druga implementacija koristei Java Semaphores i nizove. I trebate da izmerite vreme: na kraju trebate za ove tri implementacije buffera koje smo radili (koristili smo Locks i Liste, koristili smo Arrays i synchronized i na kraju koristei Arrays i Semaphores) da izmerite vreme, znai po 5 pristupa za put, 5 pristupa za get i da vidite koliko to traje TREBA DA MERITE VREME SAMO AKO NISTE BILI ZABLOKIRANI NA ONOM await(). Ako stebili zablokirani onda vreme ekanja zavisi od interakcije sa korisnikom kada e on kliknuti ono dugme na aplikaciji(ako ne klikne 10 minuta onda e 10 min biti zablokirana nit). Merite vreme samo u situacijama kada ste prolo od poetka do kraja vau metodu. U kojoj klasi ete meriti vreme za pristupanje metodi put() !? U klasi Put ete meriti vreme oko ovog poziva put() u klasi Put.Meriete vreme na nivou NANOSEKUNDE.

Strana 10 od 16

IR3KDP Laboratorijska Veba 2

Youtube transkript

CONCURRENT PROGRAM

Znai treba da preimenujete paket. Umesto .zaki stavite .bn040286. Pod dva je reeno kako da imenujete klase nazovete klase kako god ali obavezno dodate i

ClassNamebn040286. (Hints: za taku 3 nazovi klasu ArrayMessageBoxbn040286, a za taku 4


nazovi klasu SemaphoreMessageBoxbn040286). Ajde da ponovimo ovo za merenje vremena: Trebate da merite u klasi Put i Get. Neposredno pre ubacivanja/izbacivanja iz buffera. Rezultat merenje vremena koji trebate da oekujete je da je sihronizacija Niti kljunom reju synchronized BRA nego sa Semaphorima. Napomena: Poruka je generikog tipa tj telo te prouke je tipa String ali moe biti bilo kog tipa jer smo stavili da je tipa T. sa

Strana 11 od 16

IR3KDP Laboratorijska Veba 2 // interface Message<T> package rs.ac.bg.etf.kdp.rm090435d; public interface Message<T> { public T getBody(); public void setBody(T body); public long getID(); public void setID(long id); }// interface Message<T>

Youtube transkript

CONCURRENT PROGRAM

// interface MessageBox<T> package rs.ac.bg.etf.kdp.rm090435d; public interface MessageBox<T> { public void put(Message<T> m, Prioritet prioritet, long ttl); public Message<T> get(long ttd, Status status); }// interface MessageBox<T> // interface Prioritet package rs.ac.bg.etf.kdp.rm090435d; public interface Prioritet extends Comparable<Prioritet> { public static final long LOW=0; public static final long HIGH=1000; public long getLongPrioritet(); public void setLongPrioritet(long prioritet); }// interface Prioritet // class Status package rs.ac.bg.etf.kdp.rm090435d; public class Status { public static final int OK = 0; public static final int NOK = 1; int status; public Status() { this(OK); } public Status(int status) { super(); this.status = status; } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } }// class Status // class TextMessage package rs.ac.bg.etf.kdp.rm090435d; public class TextMessage implements Message<String> { String body; @Override public String getBody() { return body; } @Override public long getID() { // TODO Auto-generated method stub return 0; } @Override public void setBody(String body) { this.body=body; } @Override public void setID(long id) { // TODO Auto-generated method stub } }// class TextMessage

Strana 12 od 16

IR3KDP Laboratorijska Veba 2 Youtube transkript // class ListMessageBox<T> package rs.ac.bg.etf.kdp.rm090435d; import java.util.*; import java.util.concurrent.locks.*; public class ListMessageBox<T> implements MessageBox<T> { public static final int MAX = 2; List<Message<T>> buffer; int cap; Lock lock; Condition full, empty; public ListMessageBox() { this(MAX); } public ListMessageBox(int cap) { buffer = new LinkedList<Message<T>>(); this.cap = cap; lock = new ReentrantLock(); full = lock.newCondition(); empty = lock.newCondition(); } @Override public Message<T> get(long ttd, Status status) { lock.lock(); try { while(buffer.size()==0){ try { full.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } empty.signal(); return buffer.remove(0); } finally { lock.unlock(); } } @Override public void put(Message<T> m, Prioritet prioritet, long ttl) { lock.lock(); try { while(buffer.size()==cap){ try { empty.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } full.signal(); buffer.add(m); } finally { lock.unlock(); }

CONCURRENT PROGRAM

} }// class ListMessageBox<T>

Strana 13 od 16

IR3KDP Laboratorijska Veba 2 // class Put package rs.ac.bg.etf.kdp.rm090435d.gui; import javax.swing.*; import rs.ac.bg.etf.kdp.rm090435d.*; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.*;

Youtube transkript

CONCURRENT PROGRAM

public class Put extends JFrame { private static final long serialVersionUID = 1L; /** * FOR STATISTIC'S * Time in nanoseconds. Time variable is long. * Put line code timeStart = System.nanoTime(); in right place. * Put line code timeEnd = System.nanoTime(); in right place. */ long timeStart; long timeEnd; long dt; MessageBox<String> buffer; JButton button; JTextArea area; JPanel panelUp = new JPanel(new BorderLayout()); JPanel panelDown = new JPanel(new FlowLayout(FlowLayout.TRAILING)); public static final int MYWIDTH = 500; public static final int MYHIGHT = 400; public Put(final MessageBox<String> buffer) { super("Put"); this.buffer = buffer; setSize(MYWIDTH, MYHIGHT); setLayout(new GridLayout(2, 1)); // buffer = new ListMessageBox<String>(); // OVAKO NE MOE, NE VALJA JER NE RADI EROVANJE BUFFERA button = new JButton("Put"); area = new JTextArea(); area.setEditable(true); JScrollPane areaScrollPane = new JScrollPane(area); areaScrollPane .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); areaScrollPane.setPreferredSize(new Dimension()); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { button.setEnabled(false); Thread t = new Thread() { public void run() { Message<String> m = new TextMessage(); m.setBody(area.getText()); timeStart = System.nanoTime(); buffer.put(m, null, 0); timeEnd = System.nanoTime(); dt = timeEnd - timeStart; System.out.println("\nPut.put(Message, null,0) time evaluation:\n"+dt); button.setEnabled(true); } }; t.start(); //button.setEnabled(true);// NE MOE TO TU DA STOJI NE RADI KAKO TREBA } }); panelUp.add(areaScrollPane, BorderLayout.CENTER); panelDown.add(button); this.add(panelUp); this.add(panelDown); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); } }// class Put Strana 14 od 16

IR3KDP Laboratorijska Veba 2 Youtube transkript // class Get package rs.ac.bg.etf.kdp.rm090435d.gui; import javax.swing.*; import rs.ac.bg.etf.kdp.rm090435d.*; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.*; public class Get extends JFrame { private static final long serialVersionUID = 1L; /** * FOR STATISTIC'S * Time in nanoseconds. Time variable is long. * Put line code timeStart = System.nanoTime(); in right place. * Put line code timeEnd = System.nanoTime(); in right place. */ long timeStart; long timeEnd; long dt; MessageBox<String> buffer; JButton button; JTextArea area; JPanel panelUp = new JPanel(new BorderLayout()); JPanel panelDown = new JPanel(new FlowLayout(FlowLayout.RIGHT)); public static final int MYWIDTH = 500; public static final int MYHIGHT = 400;

CONCURRENT PROGRAM

/** * final Object reference; * ovakva deklaracija reference na objekat da je final znai * da se referenca na objekat nee menjati dok se na objekat * moe menjati koliko hoe tj stanje tog objekta. */ public Get(final MessageBox<String> buffer ) {// donji problem sa bufferom smo reili prosleivanjem ref na buffer konstruktoru super("Get"); this.buffer = buffer; setSize(MYWIDTH, MYHIGHT); setLayout(new GridLayout(2, 1)); //buffer = new ListMessageBox<String>(); // ovaj nain kreiranja buffera na ovom mestu ne valja, zbog konkuretnog okruenja button = new JButton("GET"); area = new JTextArea(); area.setEditable(true); JScrollPane areaScrollPane = new JScrollPane(area); areaScrollPane .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); areaScrollPane.setPreferredSize(new Dimension(MYWIDTH - 25, MYHIGHT)); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { button.setEnabled(false); Thread t = new Thread() { public void run() { timeStart = System.nanoTime(); Message<String> m = buffer.get(0, null); timeEnd = System.nanoTime(); dt = timeEnd - timeStart; System.out.println("\nGet.get(0,null) time evaluation:\n"+dt); area.setText(m.getBody()); button.setEnabled(true); } }; /** ako ovde umesto t.start() stavimo t.run() * poziv nee biti ispravan jer kada tako pozove * ti ne kreira nit nego obian objekat. * Znai nismo napravili Nit na taj nain ! */ t.start(); //button.setEnabled(true); } Strana 15 od 16

IR3KDP Laboratorijska Veba 2 Youtube transkript }); panelUp.add(areaScrollPane, BorderLayout.CENTER); panelDown.add(button); this.add(panelUp); this.add(panelDown); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); } }// class Get

CONCURRENT PROGRAM

// class Test package rs.ac.bg.etf.kdp.rm090435d; import javax.swing.JFrame; import rs.ac.bg.etf.kdp.rm090435d.gui.*; public class Test { public static void main(String[] args) { MessageBox<String> buffer = new ListMessageBox<String>(); // TODO - it's done and added Put put = new Put(buffer);// TODO - it's done and added Get get = new Get(buffer); put.setVisible(true); /** * ako stavi ovde code put.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); * onda kada klikne X oba prozora se unite a to ne elim * Premestio sam im u klase Put i Get. */ //put.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); get.setVisible(true); //get.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }// class Test

Strana 16 od 16