Οντοκεντρικόσ Προγραμματιςμόσ Ενότθτα 3: JAVA: ΕΞΑΙΡΕΕΙ, ΕΙΟΔΟ-ΕΞΟΔΟ, ΝΗΜΑΣΑ Νιματα Ιωάννθσ Χατηθλυγεροφδθσ Πολυτεχνικι χολι Σμιμα Μθχανικών Η/Τ & Πλθροφορικισ
ΝΗΜΑΣΑ ΣΗ JAVA
ΝΗΜΑΣΑ ΣΗ JAVA (1) Οριςμόσ Νιμα (thread) είναι μια ακολουκιακι ροι ελζγχου (δθλ. κάτι που ζχει αρχι, ακολουκία εντολών και τζλοσ) ς ζνα πρόγραμμα. Αιτία Η δυνατότθτα απομόνωςθσ (ι αυτονόμθςθσ) κάποιων εργαςιών, ώςτε να μποροφν να εκτελοφνται ταυτόχρονα. Παρατθριςεισ Ζνα νιμα δεν είναι πρόγραμμα αφ εαυτοφ του. Ζνα νιμα εκτελείται μζςα ς ζνα πρόγραμμα. Ζνα μόνο νιμα δεν προςφζρει κάτι το καινοφργιο. Δφο ι περιςςότερα νιματα μποροφν να εκτελοφνται ταυτόχρονα πραγματοποιώντασ διαφορετικζσ εργαςίεσ. 3/28
ΝΗΜΑΣΑ ΣΗ JAVA (2) Κάκε νιμα αντιπροςωπεφει μια διεργαςία. Διεργαςίεσ που εκτελοφνται ταυτόχρονα λζγονται ταυτόχρονεσ διεργαςίεσ (concurrent processes) Σθ δυνατότθτα ταυτόχρονθσ εκτζλεςθσ διεργαςιών τθν παρζχει το λειτουργικό ςφςτθμα, όπωσ π.χ. τα MS Windows, Linux. Σα ςυςτιματα αυτά επιτρζπουν τθν ταυτόχρονθ εκτζλεςθ πολλών προγραμμάτων (multitasking). Π.χ. ενώ διορκώνουμε ζνα κείμενο ςτον επεξεργαςτι κειμζνου, γίνεται μια εκτφπωςθ. Παρόμοια, ζνα μόνο πρόγραμμα μπορεί να εκτελεί ταυτόχρονα πολλζσ διεργαςίεσ (νιματα). Σζτοια προγράμματα αποτελοφν πολυνθματικζσ εφαρμογζσ (multithreaded applications). Π.χ. ο φυλλομετρθτισ HotJava είναι μια τζτοια εφαρμογι. 4/28
ΝΗΜΑΣΑ ΣΗ JAVA (3) Παραδείγματα ταυτόχρονων διεργαςιών: Κφλιςθ μιασ ςελίδασ-κατζβαςμα μιασ εικόνασ Εκτζλεςθ μιασ προςομοίωςθσ-παίξιμο ενόσ ιχου Εκτφπωςθ μιασ ςελίδασ-κατζβαςμα μιασ νζασ ςελίδασ Για να δθμιουργιςουμε μια εφαρμογι που χρθςιμοποιεί αυτι τθ δυνατότθτα πρζπει να χρθςιμοποιιςουμε μια γλώςςα που να μπορεί να διαχειριςτεί ταυτόχρονεσ διεργαςίεσ (δθλ. νιματα). Μια τζτοια γλώςςα είναι θ Java. Σο είδοσ προγραμματιςμοφ που αςχολείται με τθ διαχείριςθ ταυτόχρονων διεργαςιών ονομάηεται ταυτόχρονοσ προγραμματιςμόσ (concurrent programming). 5/28
ΚΤΚΛΟ ΖΩΗ ΝΗΜΑΣΟ γεννηθέν (born) start εκτελέσιμο (runnable) End of sleeping time resume yield notify notifyall I/O completion αναπαυόμενο (sleep) ανασταλλέν (suspended) αναμένον (waiting) αποκλεισμένο (blocked) sleep suspend dispatch wait I/O request εκτελούμενο (running) stop complete νεκρό (dead) 6/28
ΔΗΜΙΟΤΡΓΙΑ ΝΗΜΑΣΩΝ ΣΗ JAVA Δφο τρόποι δθμιουργίασ νθμάτων: (α) αν ςτιγμιότυπα υποκλάςεων τθσ κλάςθσ Thread (β) αν ςτιγμιότυπα υλοποιιςεων τθσ διεπαφισ Runnable (όταν θ κλάςθ που δθμιουργείται πρζπει να είναι υποκλάςθ κάποιασ άλλθσ κλάςθσ, π.χ. τθσ Applet) Και ςτισ δφο περιπτώςεισ πρζπει να οριςτεί το ςώμα τθσ μεκόδου void run(), που είναι κενό και προςδιορίηει τι κάνει το νιμα. Η μζκοδοσ run() είναι (αφθρθμζνθ) μζκοδοσ τθσ Runnable, αλλά και τθσ Thread (διότι θ Thread υλοποιεί τθν Runnable). 7/28
ΚΛΑΗ THREAD-ΜΕΘΟΔΟΙ Άλλεσ μζκοδοι τθσ Thread είναι: start() :Απαιτείται θ κλιςθ τθσ για να ενεργοποιθκεί το νιμα. sleep(n) :Κακορίηει το χρόνο n (ςε msec) που (κζλουμε να) κακυςτερεί το νιμα πριν αρχίςει θ εκτζλεςι του (το n είναι τφπου long). Εγείρει εξαίρεςθ τφπου InterruptedException. interrupted() :Επιςτρζφει true, αν το νιμα είναι ςε διακοπι, αλλιώσ false. interrupt() :Διακόπτει τθν εκτζλεςθ του νιματοσ. suspend() :Αναςτζλλει τθν εκτζλεςθ του νιματοσ. resume() :Επαναρχίηει θ εκτζλεςθ του νιματοσ. stop() :Σερματίηει τθν εκτζλεςθ του νιματοσ. isalive() :Επιςτρζφει true, αν ζχει ενεργοποιθκεί το νιμα (ζχει κλθκεί θ start και δεν ζχει τερματιςτεί), αλλιώσ false. 8/28
ΚΛΑΗ THREAD-ΔΗΜΙΟΤΡΓΟΙ Η Thread διακζτει αρκετοφσ δθμιουργοφσ. Οι πιο δθμοφιλείσ είναι: Thread () Thread (String name) Thread (Runnable object) Thread (Runnable object, String name) όπου name είναι το όνομα του νιματοσ και object ζνα αντικείμενο τφπου Runnable. 9/28
ΝΗΜΑΣΑ ΜΕ ΧΡΗΗ ΣΗ THREAD (1) Διαδικαςία δθμιουργίασ νιματοσ Δθμιουργία μιασ υποκλάςθσ τθσ Thread Τλοποίθςθ τθσ run ςτο ςώμα τθσ υποκλάςθσ. Δθμιουργία ςτιγμιοτφπου τθσ υποκλάςθσ Κλιςθ τθσ start από το ςτιγμιότυπο Λειτουργία μεκόδου start Δθμιουργεί το νζο νιμα εκτζλεςθσ Καλεί τθ μζκοδο run Επιςτρζφει τον ζλεγχο ςτο ςθμείο κλιςθσ τθσ 10/28
ΝΗΜΑΣΑ ΜΕ ΧΡΗΗ ΣΗ THREAD (2) (δθμιουργόσ) (υλοποίθςθ τθσ run) public class SimpleThread extends Thread { public SimpleThread(String str) { super(str); public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getname()); try { Thread.sleep((int) (Math.random() * 1000)); catch (InterruptedException e) { System.out.println("DONE! " + getname()); 11/28
ΝΗΜΑΣΑ ΜΕ ΧΡΗΗ ΣΗ THREAD (3) public class TwoThreadsDemo { public static void main (String[] args) { thread1 = new SimpleThread( Patra ); thread2 = new SimpleThread( Athina ); thread1. start(); thread2. start(); (δθμιουργία νθμάτων ωσ ςτιγμιότυπα τθσ SimpleThread και κλιςθ τθσ start) 12/28
ΝΗΜΑΣΑ ΜΕ ΧΡΗΗ ΣΗ THREAD (4) public class TwoThreadsDemo { public static void main (String[] args) { new SimpleThread( Patra ).start(); new SimpleThread( Athina ).start(); (δθμιουργία νθμάτων ωσ ςτιγμιότυπα τθσ SimpleThread και κλιςθ τθσ start) 13/28
ΕΚΣΕΛΕΗ ΝΗΜΑΣΩΝ 0 Patra 0 Athina 1 Athina 1 Patra 2 Patra 2 Athina 3 Athina 3 Patra 4 Patra 4 Athina 5 Patra 5 Athina 6 Athina 6 Patra 7 Patra 7 Athina 8 Athina 8 Patra 9 Athina 9 Patra DONE! Athina DONE! Patra 14/28
ΝΗΜΑΣΑ ΜΕΩ ΣΗ RUNNABLE Διαδικαςία δθμιουργίασ νιματοσ Δθμιουργία κλάςθσ που υλοποιεί τθν Runnable Τλοποίθςθ τθσ run ςτο ςώμα τθσ κλάςθσ. Δθμιουργία ςτιγμιοτφπου τθσ κλάςθσ Δθμιουργία ςτιγμιοτφπου τθσ Thread με όριςμα το ςτιγμιότυπο τθσ κλάςθσ Κλιςθ τθσ start από το ςτιγμιότυπο τθσ Thread 15/28
ΝΗΜΑΣΑ ΜΕΩ ΣΗ RUNNABLE (1) 1. Δθμιουργία κλάςθσ 2. Υλοποίθςθ run public class CountUp implements Runnable { public void run() { for (int i=0; i < 0; i++) System.out.println( CountUp- + i); 3. Δθμιουργία ςτιγμιοτφπου τθσ CountUp CountUp counter1 = new CountUp(); 4. Δθμιουργία ςτιγμιοτφπου Thread με όριςμα δθμιουργοφ counter1 Thread thread1 = new Thread(counter1); 5. Κλιςθ μεκόδου start thread1.start(); 16/28
ΝΗΜΑΣΑ ΜΕΩ ΣΗ RUNNABLE (2) public class Clock extends Applet implements Runnable { private Thread clockthread = null; public void start() { if (clockthread == null) { clockthread = new Thread(this, "Clock"); clockthread.start(); public void run() { Thread mythread = Thread.currentThread(); while (clockthread == mythread) { repaint(); try { Thread.sleep(1000); catch (InterruptedException e){ 17/28
ΤΓΧΡΟΝΙΜΟ ΝΗΜΑΣΩΝ (1) Μζχρι τώρα αναφερκικαμε ςε νιματα εκτελοφνται ανεξάρτθτα το ζνα από το άλλο. Δεν απαιτείται το ζνα να γνωρίηει ςχετικά με τισ εργαςίεσ των άλλων. Τπάρχουν όμωσ περιπτώςεισ που τα νιματα πρζπει να μοιράηονται δεδομζνα. τθν περίπτωςθ αυτι πρζπει να εξαςφαλίςουμε ότι το ζνα νιμα δεν κα αλλάξει τα δεδομζνα ενόςω τα διαχειρίηεται άλλο νιμα. Περίπτωςθ που μπορεί να δθμιουργθκεί τζτοιο πρόβλθμα υπάρχει όταν διαφορετικά αντικείμενα μιασ κλάςθσ διαχειρίηονται ςτατικζσ μεταβλθτζσ ι ςτατικζσ μεκόδουσ τθσ κλάςθσ. 18/28
ΤΓΧΡΟΝΙΜΟ ΝΗΜΑΣΩΝ (2) Για τθν αντιμετώπιςθ τζτοιων καταςτάςεων θ Java επιτρζπει το κλείδωμα αντικειμζνων και μεκόδων με τθ χριςθ τθσ δεςμευμζνθσ λζξθσ synchronized. Ζτςι επιτυγχάνεται ο λεγόμενοσ ςυγχρονιςμόσ νθμάτων, ο οποίοσ επιτρζπει τθν προςπζλαςθ μιασ μεκόδου (ι ενόσ αντικειμζνου) ς ζνα μόνο νιμα κάκε φορά. Μια μζκοδοσ ςυγχρονίηεται ωσ εξισ: public synchronized void xmethod, - Για να προςπελάςει ζνα νιμα μια μζκοδο που ζχει δθλωκεί ωσ synchronized, πρζπει να περιμζνει να τελειώςει το τρζχον νιμα (blocked). (Ζλεγχοσ μζςω monitor object). 19/28
ΤΓΧΡΟΝΙΜΟ ΝΗΜΑΣΩΝ (3) Μποροφμε επίςθσ να δθλώςουμε ωσ ςυγχρονιςμζνο ζνα τμιμα κώδικα ςτο ςώμα μιασ μεκόδου, αντί όλθσ τθσ μεκόδου: public int ymethod { synchronized (this) { 20/28
ΤΓΧΡΟΝΙΜΟ ΝΗΜΑΣΩΝ (4) Για μεγαλφτερθ αςφάλεια και αποφυγι αδιεξόδων, τα μζρθ του κώδικα που ζχουν δθλωκεί ωσ synchronized πρζπει να περιλαμβάνουν κλιςεισ τθσ μεκόδου wait(): try { <κώδικασ> wait(); catch (InterruptedException e) { Η κλιςθ τθσ wait προκαλεί αναςτολι τθσ εκτζλεςθσ του νιματοσ, μζχρισ ότου ζνα άλλο νιμα καλζςει τθ μζκοδο notify() ι notifyall() (μετακζτουν ζνα ι όλα τα νιματα από κατάςταςθ αναςτολισ ςε κατάςταςθ ετοιμότθτασ). 21/28
ΠΡΟΣΕΡΑΙΟΣΗΣΕ ΝΗΜΑΣΩΝ Τπάρχουν περιπτώςεισ που κζλουμε τα νιματα να μθν είναι ιςοδφναμα, αλλά κάποια να εκτελοφνται περιςςότερο χρόνο από άλλα. Αυτό επιτυγχάνεται με τον κακοριςμό προτεραιότθτασ για κάκε νιμα (1-10). Η κανονικι προτεραιότθτα είναι 5. Η Thread διακζτει τρεισ ςτακερζσ MAX_PRIORITY, MIN_PRIORITY και NORM_PRIORITY με τιμζσ 10, 1 και 5. Η προτεραιότθτα ενόσ νιματοσ τίκεται με τθν setpriority (int priority), ενώ με τθν getpriority() μποροφμε να ανιχνεφςουμε τθν τρζχουςα τιμι προτεραιότθτασ ενόσ νιματοσ. 22/28
Χρθματοδότθςθ Σο παρόν εκπαιδευτικό υλικό ζχει αναπτυχκεί ςτo πλαίςιo του εκπαιδευτικοφ ζργου του διδάςκοντα. Σο ζργο «Ανοικτά Ακαδθμαϊκά Μακιματα ςτο Πανεπιςτιμιο Ακθνών» ζχει χρθματοδοτιςει μόνο τθν αναδιαμόρφωςθ του εκπαιδευτικοφ υλικοφ. Σο ζργο υλοποιείται ςτο πλαίςιο του Επιχειρθςιακοφ Προγράμματοσ «Εκπαίδευςθ και Δια Βίου Μάκθςθ» και ςυγχρθματοδοτείται από τθν Ευρωπαϊκι Ζνωςθ (Ευρωπαϊκό Κοινωνικό Σαμείο) και από εκνικοφσ πόρουσ. 23/28
θμείωμα Ιςτορικοφ Εκδόςεων Ζργου Σο παρόν ζργο αποτελεί τθν ζκδοςθ 1.0. 24/28
θμείωμα Αναφοράσ Copyright: Πανεπιςτιμιον Πατρών, Ιωάννθσ Χατηθλυγεροφδθσ, 2015. «Οντοκεντρικόσ Προγραμματιςμόσ». Ζκδοςθ: 1.0. Πάτρα 2015. Διακζςιμο από τθ δικτυακι διεφκυνςθ: https://eclass.upatras.gr/courses/ceid1105/ 25/28
θμείωμα Αδειοδότθςθσ Σο παρόν υλικό διατίκεται με τουσ όρουσ τθσ άδειασ χριςθσ Creative Commons Αναφορά, Μθ Εμπορικι Χριςθ Παρόμοια Διανομι 4.0 *1+ ι μεταγενζςτερθ, Διεκνισ Ζκδοςθ. Εξαιροφνται τα αυτοτελι ζργα τρίτων π.χ. φωτογραφίεσ, διαγράμματα κ.λ.π., τα οποία εμπεριζχονται ςε αυτό και τα οποία αναφζρονται μαηί με τουσ όρουσ χριςθσ τουσ ςτο «θμείωμα Χριςθσ Ζργων Σρίτων». [1] http://creativecommons.org/licenses/by-nc-sa/4.0/ Ωσ Μθ Εμπορικι ορίηεται θ χριςθ: που δεν περιλαμβάνει άμεςο ι ζμμεςο οικονομικό όφελοσ από τθν χριςθ του ζργου, για το διανομζα του ζργου και αδειοδόχο που δεν περιλαμβάνει οικονομικι ςυναλλαγι ωσ προχπόκεςθ για τθ χριςθ ι πρόςβαςθ ςτο ζργο που δεν προςπορίηει ςτο διανομζα του ζργου και αδειοδόχο ζμμεςο οικονομικό όφελοσ (π.χ. διαφθμίςεισ) από τθν προβολι του ζργου ςε διαδικτυακό τόπο Ο δικαιοφχοσ μπορεί να παρζχει ςτον αδειοδόχο ξεχωριςτι άδεια να χρθςιμοποιεί το ζργο για εμπορικι χριςθ, εφόςον αυτό του ηθτθκεί.
Διατιρθςθ θμειωμάτων Οποιαδιποτε αναπαραγωγι ι διαςκευι του υλικοφ κα πρζπει να ςυμπεριλαμβάνει: το θμείωμα Αναφοράσ το θμείωμα Αδειοδότθςθσ τθ διλωςθ Διατιρθςθσ θμειωμάτων το θμείωμα Χριςθσ Ζργων Σρίτων (εφόςον υπάρχει) μαηί με τουσ ςυνοδευόμενουσ υπερςυνδζςμουσ. 27/28
θμείωμα Χριςθσ Ζργων Σρίτων 28/28