Download - Java Lichidari Hatz
Cluj-Napoca - 30 septembrie 2015
Limbaje de programare – curs 1 - - Informatică Economică, an III –
Gheorghe Cosmin Silaghi
Introducereinobiectualitate.Operatori.Controlulexecu4eiprogramelor
Cluj-Napoca - 30 septembrie 2015
Cuprins
• Principiile programarii obiectuale • Notiunea de obiect
Cluj-Napoca - 30 septembrie 2015
Principii de bază în obiectualitate (II)
• Programare obiectuală: Elemente din spaţiul problemei precum si reprezentarile
acestora in spatiul solutiei ó obiecte
• Caracteristici ale limbajelor obiectuale 1. Orice element este un obiect 2. Un program este o colecţie de obiecte care isi spun unul
altuia ce sa faca prin trimitere de mesaje 3. Fiecare obiect are un spaţiu de memorie, posibil compus
din alte obiecte 4. Fiecare obiect are un tip 5. Toate obiectele de acelaşi tip pot primi acelaşi mesaj
(atentie: proprietatea de upcast)
Cluj-Napoca - 30 septembrie 2015
Principii de bază în obiectualitate (III)
• Definitia Booch pentru un obiect: un obiect are o stare, un comportament si o identitate
• Clasă: set de obiecte cu caracteristici şi funcţionalitate identice (termenul de clasa se substituite termenului de tip)
• Intefaţa: metode (funcţionalitate): cererile care pot fi adresate unui obiect particular dintr-o clasa
• Implementarea: mod concret de realizare a funcţionalităţii
• Un obiect poate fi privit ca si furnizor de servicii • Se imbunatateste coeziunea obiectelor (obiectele trebuie sa se
potriveasca bine unele cu altele)
UML – reprezentarea claselor
• UML: limbaj standardizat pentru modelarea obiectuala
Light lt = new Light(); lt.on();
Cluj-Napoca - 30 septembrie 2015
Numede4p-> Light
Interfata->on()off()brighten()dim()
Ascunderea implementarii
• 2 tipuri de programatori: – creatori de clase – creaza clase care expun doar functionalitatea necesara
claselor client, restul ramane ascuns – programatori client – consumatori de clase, rolul lor este sa fie echipati cu un set
de clase pentru dezvoltarea rapida a aplicatiilor finale
• Programatorii creatori de clase trebuie sa poata schimba implementarea ascunsa fara ca programatorii clienti sa fie afectati
• Speficatori de access: – Private: elementele private pot fi accesate doar de creatorul clasei in cadrul
metodelor acelei clase – Public: elementele publice sunt disponibile oricaror alte clase – Protected: similar cu private, utilizat in mostenire, clasele care mostenesc pot
accesa elementele private din clasele de baza
Cluj-Napoca - 30 septembrie 2015
Cluj-Napoca - 30 septembrie 2015
Reutilizarea implementarii - compozitie
• Managementul complexităţii: descompunerea elementelor problemei în părţi componente
• 2 metode de realizare a complexităţii:
– Compoziţie: o clasă nouă conţine clase existente Relaţie has-a Se realizeaza prin creare de obiecte membre Compozitia realizata dinamic se numeste agregare
Reutilizarea implementarii - mostenire • Datele si functionalitatile se pot impacheta dupa concepte care
reprezinta idei similare din spatiul problemei
– Moştenire: o clasă nouă se aseamănă (extinde) o clasă existentă Relaţie is-a sau is-like-a
• Clasa de baza – contine caracteristicile si comportamentele care vor fi partajate cu tipurile derivate
• Clasa derivata
• Clasa derivata va contine – toti membrii clasei de baza (inclusiv cei privati care sunt ascunsi) – Toata interfata clasei de baza, care este duplicata
• Clasa derivata este in acelasi timp de tipul clasei de baza
Cluj-Napoca - 30 septembrie 2015
Cluj-Napoca - 30 septembrie 2015
Mostenire – cum se diferentiaza clasa derivata de clasa de baza
• Prin adaugare de noi metode suplimentare • Schimbarea comportamentului unor metode existente in clasa de baza
(overriding)
• Relatia is-a: clasa derivata doar override metode din clasa de baza (principiul substitutiei pure)
• Relatia is-like-a: clasa derivata adauga elemente noi interfetei clasei de baza (metodele noi nu sunt accesibile din clasa de baza – substitutia nu mai este pura)
Cluj-Napoca - 30 septembrie 2015
Obiecte interschimbabile prin polimorfism
" Laierarhiiledeclasedorimsatratamobiecteleunitar,sub4puldebaza
" AsDel,putemscriecodcarenudepindedeun4pspecificsicaremanipuleazaobiectegenerice
" Sedorestecasăseexecutecoduldinobiecteleclaselorderivatefărăcasăs4m(lacompilare)carevorfiefec4vacesteobiecte
" Compilatoaretradi4onale(nonOOP)–earlybinding" CompilatoareOOP–latebinding–codulapelatestedeterminatabia
laexecu4e,lacompilareseasiguradoarcorespondenta4puluiargumentelorsia4puluidereturn
" Java–compilatorOOP–dynamic(late)binding" Proprietateadeupcast:tratareaunuiobiectdintr-oclasăderivatăca
sicumarfidinclasadebaza
Cluj-Napoca - 30 septembrie 2015
Ierarhie cu o singura radacina
" InJava(siinoricelimbajobiectualcuexcep4aC++)toateclaselemostenescoclasadebazanumităObject
" AsDel,toateobiecteledinlimbajpotfiechipateinmodgarantatcuanumităfunc4onalitate
" Seusureazaimplementareagarbagecollectorului
Cluj-Napoca - 30 septembrie 2015
Containere
• Necesare datorita faptului ca nu stim de la design numarul de obiecte necesare pentru a rezolva o anumita problema
• Containerele sunt siruri de referinte catre alte obiecte • Ele se expandeaza automat pentru a salva noi obiecte, dupa
necesitati • 2 tipuri de liste: ArrayList, LinkedList • Containerele in Java sunt create sa pastreze obiecte de tipul
Object. -> ele pot salva orice • Pot aparea exceptii la Downcast la runtime, timp de executie
crescut datorită operației de Downcast • Containere parametrizate:
– ArrayList<Shape> shape = new ArrayList<Shape>();
Cluj-Napoca - 5 Octombrie 2015
Limbaje de programare – curs 2 - - Informatică Economică, an III –
Gheorghe Cosmin Silaghi
No4uniintroduc4veJavaIni4alizareaobiectelor
Organizarea codului
• Pentru fiecare clasa compilata se produce un fisier .class • Un program este compus dintr-o colectie de fisiere .class • Acestea pot fi arhivate: fisier .jar • Fiecare fisier .java incepe cu mentiunea “package”: se indica numele
packageului din care vor face parte clasele • Clasele utilizate care fac parte din alt package se importa cu “import” • Toate clasele dintr-un package vor fi colectate intr-un singur subdirector • Conventie pentru denumirea packageurilor: utilizarea domeniilor de internet
in ordine inversa • Calea root pentru directorare: variabila sistem CLASSPATH • CLASSPATH poate include directoare sau fisiere .jar
Cluj-Napoca - 5 Octombrie 2015
Crearea obiectelor si ciclul de viata
• Fiecare obiect necesita resurse (memorie), crearea si distrugerea obiectelor devin importante
• Java utilizeaza in mod exclusiv alocarea dinamica a memoriei • Pentru orice obiect, trebuie utilizat new la creeere • Obiectele sunt alocate in zona de heap • Distrugerea obiectelor este realizata automat de catre garbage collector • GC identifică momentul in care un obiect nu mai este utilizat și il dezalocă
Cluj-Napoca - 5 Octombrie 2015
Numele de obiecte - referinte
• Identificatorii prin care se manipuleaza obiectele sunt referinte catre obiecte
• De ex: String s; // se creaza o referinta catre un obiect de tip String • String s = new String(“asdf”); // referinta creata este initializata
• Toate variabilele (referintele) create in program trebuie initializate!!!
Cluj-Napoca - 5 Octombrie 2015
v Zona Registru: registrele procesorului, nu avem access direct la ele v Stiva: zona de stiva memoreaza referintele catre obiecte v Heap: in aceasta zona sunt alocate toate obiectele (la apelul new) v Spatiu de stocare non-RAM: obiecte care exista in afara spatiului de
memorie a programului (persistenta obiectelor)
Tipurile primitive v Variabile de dimensiune mica, salvate direct pe stiva, v Nu necesita new la alocare v boolean, char, byte, short, int, long, float, double si void v Fiecare din acestea are un wrapper type pentru construirea obiectului
din tipul corespondent
v Autoboxing: conversie automata de la un tip primitiv la wrapper Character ch = ‘x’;
Cluj-Napoca - 5 Octombrie 2015
Organizarea memoriei in Java
Numere de inalta precizie • BigInteger si BigDecimal • Sunt vazute ca si clase de tip Wrapper insa nu au un tip primitiv
corespondent
Siruri (Arrays) in Java • Java: limbaj de programare orientat safety • La crearea unui Array se creaza un sir de referinte fiecare initializata la
valoarea null • => fiecare membru al sirului trebuie initializat • Java nu permite utilizarea unui indice in afara range-ului array-ului (se
arunca o exceptie)
Cluj-Napoca - 5 Octombrie 2015
Cluj-Napoca - 5 Octombrie 2015
Domenii de vizibilitate in Java
• Intre o acolada deschisa si una inchisa avem un domeniu de vizibilitate (la fel ca in C/C++)
• Java determina cand un obiect nu mai este referit de catre nici o referinta dintr-un domeniul de vizibilitate valid => se apeleaza garbage collector pentru dezalocarea memoriei
Cluj-Napoca - 5 Octombrie 2015
Clase
class ATypeName { /* class body */}
Clasele contin: - Campuri - Metode
Modul de accesare a unui camp/metoda objectReference.member
Pentru datele din tipuri primitive se garanteaza initializarea la valori implicite (false si 0)
Metode, argumente si tip de return ReturnType methodName(/* argument list */) { /* method body*/ }
Vizibilitatea numelor • Pentru a produce nume de biblioteci unice, s-a realizat conventia ca
fiecare programator sa isi utilizeze propriul nume de domeniu de internet ca si nume de biblioteca
ex: ro.ubbcluj.econ.gsilaghi
• Punctul in numele bibliotecii reprezinta un subdirector de pe disc
Utilizarea altor componente: import • import java.util.ArrayList; // se importa o clasa • import java.util.*; // se importa tot packageul java.util
Cluj-Napoca - 5 Octombrie 2015
Cuvantul cheie static • Datele membre si metodele pot fi accesate doar sub calificarea
unui obiect existent in memoria programului (creat cu new) • Un camp sau o metoda statica nu este legata de vreun obiect
anume dintr-o clasa • class data sau class method • Un camp static exista o singura data pentru o clasa, fiind
partajat de toate obiectele clasei respective • Campurile statice pot fi referite prin numele clasei • Metodele statice sunt la nivel de clasa, pot fi referite prin
numele clasei (fara a fi necesara existenta unui obiect) • Metoda main • Metodele statice nu pot accesa campuri/metode ne-statice din
clasa
Cluj-Napoca - 5 Octombrie 2015
Cluj-Napoca - 5 Octombrie 2015
Stil de scriere a codului
• Code conventions for the Java Language • Numele clasei din mai multe cuvinte cu capitalizarea fiecarui cuvant
din nume • Pentru orice altceva (metode, campuri, referinte de obiecte) prima
litera e litera mica
Operatori • Toti operatorii produc o valoare prin aplicarea lor • Ei pot produce si side-effects (modificarea valorii operanzilor) • Operatorul de atribuire =
– a= 4; // atribuirea unei valori dintr-un tip primiti unei variabile – Daca c si d sunt obiecte, c=d; // ambele (c si d) vor referi acelasi obiect (d)
• Aliasing: la transmiterea unui obiect ca si argument intr-o metoda, se transmite o referinta, deci modificarea valorii in metoda afecteaza valoarea obiectului din afara metodei
• Operatorii ++ si – au forma postfixata si prefixata (similar cu C/C++) • Operatorii == si =! Aplicati pe referinte de obiecte, compara referintele, si
nu continutul obiectelor • Pentru compararea continutului obiectelor, metoda equals:
– n1.equals(n2);
• Pentru clasa String se pot folosi + si +=
Cluj-Napoca - 5 Octombrie 2015
Cluj-Napoca - 5 Octombrie 2015
Controlul executiei
• if-then-else • while, do-while, for • foreach: pentru a selecta un element dintr-un array si a efectua o
prelucrare pe acel element – foreach functioneaza pentru orice sir de obiecte Iterable
• Intreruperea executiei unei secvente: return, break, continue • switch: instructiunea de selectie din mai multe alternative
Cluj-Napoca - 5 Octombrie 2015
Initializarea obiectelor
" Infiecareclasasegaranteazaini4alizareaobiectelorprinscriereaunuiconstructor
" Lacreareaunuiobiect,Javaapeleazaautomatconstructorulclaseirespec4ve
" Numeleconstructoruluiesteiden4ccunumeleclasei" Constructoruldefault:nuareargumente" Constructorulnuare4pdereturn" Dacasecreazaoclasafărăniciunconstructor,compilatorulcreazăin
modautomatconstructoruldefault
Cluj-Napoca - 5 Octombrie 2015
Supraincarcarea metodelor
" U4lizareaaceluiasinumedemetodapentrumaimultemetodecuargumentediferite
" Cumdiferen4azaJavaintremetodelesupraincarcate:acestemetodetrebuiesădifereprinlistaargumentelor
" Lasupraincarcare,primi4veledinlistadeargumentesunt“promoted”catre4purilemailargi
" Metodelenusepotsupraincarcape4puldereturn
Cluj-Napoca - 5 Octombrie 2015
Cuvantul cheie this
• In fiecare metoda apelata, referinta obiectului sub care se apeleaza metoda este transmisa in metoda sub forma referintei this
• this poate fi utilizat doar in interiorul metodelor ne-statice • In interiorul unei metode dinstr-o clasa, la apelul unei metode din clasa
curenta, nu este nevoie sa se utilizeze this • This este frecvent utilizat in return, pentru a returna obiectul curent
Distrugerea obiectelor
• Garbage collector-ul dezaloca memoria alocata prin new, atunci cand obiectele nu mai sunt folosite
• Metoda finalize(): permite operatii de stergere inainte ca obiectele sa fie supuse garbage collectorului
• Metoda finalize(): Java nu garanteaza apelarea acestei metode, programatorul nu are control asupra momentului cand se apeleaza garbage collectorul
• Daca obiectele noastre agrega alte obiecte, garbage collectorul se ocupa de dezalocarea obiectelor agregate
• Finalize se utilizeaza in general pentru a implementa termination conditions pentru un obiect (de exemplu inchiderea unui fisier)
Cluj-Napoca - 5 Octombrie 2015
Cluj-Napoca - 12 Octombrie 2015
Stergerea corectă a obiectelor
• Java nu garantează apelarea metodei finalize la distrugerea obiectelor
• Ce se intamplă atunci când este necesar ca obiectele să fie sterse daca programele se termină cu exceptie?
• Se pune codul de stergere intr-o metodă dispose • Metoda dispose se apelează pe clauza finally a unui try-catch global
• La stergerea obiectelor, aceasta trebuie să se realizeze in ordine inversă a creerii obiectelor. -> programatorul trebuie să se asigure de acest lucru
Modul de functionare a garbage collectorului • GC colecteaza memoria ramasa alocata in obiectele care nu mai sunt
utilizate si compacteaza heap-ul, rearanjand obiectele alocate • Reference couting: o modalitate de a implementa un GC:
– De cate ori se asociaza o referinta pentru un obiect, reference counterul obiectului se incrementeaza
– De cate ori se pierde o referinta pentru o obiect, reference counterul obiectului se decrementeaza
– GC scaneaza sirul de variabile reference counters si cand intalneste una nula, dezaloca obiectul respectiv
• Implementarea Java: pentru un obiect live se poate identifica o referinta fie pe stack fie in static storage
• Stop-and-copy: GC-ul opreste programul, scaneaza toate referintele de pe stack si copiaza obiectele identificate in noul heap. Ceea ce ramane e garbage-ul care trebuie dezalocat, iar noul heap e deja compactat
Cluj-Napoca - 5 Octombrie 2015
Initializarea datelor membre • Utilizarea unei variabile locale neinitializate => eroare de compilare • Orice data membra a unei clase, daca este de tip primitiv, se
garanteaza initializare la valoarea implicita • Obiectele membre neinitializate, vor avea valoarea null • Specificarea valorii de initializare:
– La momentul definirii variabilei primitive prin asignare cu o valoare – La momentul definirii variabilei non-primitive, prin new
• Initializarea datelor membre prin constructor • Ordinea de initializare a datelor membre: ordinea in care acestea sunt
definite in clasa • Initializarea datelor statice are loc doar daca acestea sunt necesar a fi
utilizate • Obiectele statice sunt initializate inaintea celor non-statice, daca ele nu
au fost utilizate pana atunci
Cluj-Napoca - 5 Octombrie 2015
Procesul creerii unui obiect • Presupunem ca avem o clasa Dog • Prima data cand un obiect de tip Dog este creat, JVM localizeaza pe disc
fisierul Dog.class si il incarca • La incarcarea Dog.class, se initializeaza toti membrii statici • La new Dog() se aloca memorie pe heap pentru noul obiect, aceasta zona
de memorie se umple cu 0 (primitivele sunt initializate la valoarea implicita) • Se realizeaza toate initializarile explicite la momentul definirii datelor
membre • Se executa constructorul
Cluj-Napoca - 5 Octombrie 2015
Blocul static • static {/* initializari */}; • Blocul static este apelat o singura data, la prima creare a unui obiect
din clasa respectiva sau la apelarea unei membre statice din acea clasa • Blocul static poate sa initializeze doar date statice
Initializare prin bloc non-static • { /* operatii */ }; // fara static inainte • Intre acolade se specifica operatii de initializare care trebuie efectuate
indiferent de care constructor este apelat • Blocul non-static de initializare este necesar pentru a se permite
definirea claselor interne anonime
Cluj-Napoca - 5 Octombrie 2015
Initializarea sirurilor
• Sirurile sunt definite prin operatorul de indexare: int[] a; • Pentru a se crea spatiu de memorie pentru sir, sirul trebuie initializat • Fiecare sir are un membru intrinsec: length (lungimea sirului) • Elementele sunt indexate de la 0 la length-1
• Integer[] a = new Integer[rand.nextInt(20)]; // se creaza doar un sir de referinte, fiecare din ele trebuie apoi initializate, de ex:
• a[i] = rand.nextInt(500);
Cluj-Napoca - 5 Octombrie 2015
Controlul accesului - clase
• Package: clase grupate impreuna intr-un singur spatiu de nume logic • Orice clasă dintr-un package poate face referire directă la o alta clasă
din același package • Pentru accesarea claselor din alte package-uri se utilizează import • Lipsa definitiei de package: package-ul default.
– Nu se recomandă utilizarea acestuia
• Specificatorul de access public la clase: – Pentru a putea fi referita din afara packageului
• Clasele fără specificator de access: nu pot fi referite din afara package-ului
Cluj-Napoca - 5 Octombrie 2015
Controlul accesului – membrii claselor
• Public: – membrii publici pot fi referiti din afara claselor – Specifică interfața claselor
• Private: – Pot fi referiti doar din interiorul claselor de definire – Specifica implementarea claselor
• Fără specificator de access – access package: – Pot fi referiți din clasele packege-ului curent
• Protected: folosit in contextul mosternirii
Cluj-Napoca - 5 Octombrie 2015
Cluj-Napoca - 12 Octombrie 2015
Limbaje de programare – curs 4 - - Informatică Economică, an III –
Gheorghe Cosmin Silaghi
Reu4lizareaclaselor
Cluj-Napoca - 12 Octombrie 2015
Cuprins
• Compozitie • Mostenire • Alegerea intre compozitie si mostenire • Mecanismul de upcast
Reutilizarea codului
• Înseamnă mult mai mult decât copy-paste de cod • Operații principale: compoziție și mostenire • Sintaxa compoziției: se plasează o referință către un obiect nou într-o
clasă nouă • Referintele nou create se initializează la valoarea null -> trebuie
initializate explicit • Metoda toString: mostenită de la clasa Object: se permite convertirea
obiectului intr-un obiect String (necesar pentru tipărire)
Cluj-Napoca - 12 Octombrie 2015
Initializarea referintelor la realizarea compozitiei
• Initializarea se poate realiza in 4 moduri: – La momentul definirii obiectului – initializarea se face inainte de apelarea
constructorului – In constructor – Chiar inainte de utilizarea obiectului (lazy initialization) – Instance initialization – in bloc non-static de initializare
Cluj-Napoca - 12 Octombrie 2015
Sintaxa mostenirii • Mostenirea se realizează ori de câte ori se crează o clasă: se moștenește din
Object • Mostenire: clasa nouă se aseamănă cu clasa veche: cuvântul cheie extends • Clasa nouă va prelua automat toate campurile și metodele din clasa de bază • Regulă nescrisă la mostenire: câmpurile din clasele de bază se scriu private
iar metodele se lasă public (sau protected) • Clasa derivată poate să preia o metodă din clasa de bază si să o rescrie • Din clasa derivată, pentru a se apela o metodă din clasa de bază se poate
utiliza super • Realizarea mostenirii: la crearea obiectului din clasa derivată, se crează un
subobiect din clasa de bază (ca si cum ar fi realizată o compozitie către acesta)
• Initializarea subobiectului din clasa de bază: doar prin constructor • Constructorul clasei de bază este apelat intotdeauna inaintea constructorului
clasei derivate • Pentru apel al constructorului clasei de bază cu argumente:
– super ( argumente)
Is-a vs. Is-like-a • Relatie de mostenire de tip is-a: clasa derivată doar suprascrie interfața
clasei de bază • Relatie de mostenire de tip is-like-a: clasa derivată contine metode
suplimentare față de clasa de bază • Relația de substituție:
– La o relatie de tip is-a substitutia este pură: orice mesaj trimis clasei derivate poate fi trimis si clasei de bază (rezolvarea mesajului se face prin upcast)
– La o relație de tip is-like-a: partea extinsă din clasa derivată nu mai este disponibilă prin upcast (prin adresarea clasei de bază)
• Downcast: operația inversă upcast – nu este o operație garantată, in sensul in care nu stim exact clasa derivată către care se face downcast
• Java verifică orice conversie (cast), si daca nu se poate realiza se aruncă o exceptie de tipul ClassCastException
Cluj-Napoca - 12 Octombrie 2015
Operatia de delegare • Operatie intermediară intre compozitie si agregare • Intr-o clasă se plasează un obiect membru din a 2-a clasă, iar clasa
nouă va expune toate metodele furnizate de obiectul din clasa 2-a
• Pentru realizarea operatiilor de mostenire / compozitie, este suficient ca să se importe clasele reutilizate (codul lor sursă nu este necesar)
Cluj-Napoca - 12 Octombrie 2015
Cluj-Napoca - 12 Octombrie 2015
Ascunderea numelor la mostenire
• La suprascrierea unei metode supraincarcate din clasa de bază, numele supraincarcate din clasa de bază nu devin ascunse!!!
• Supraincarcarea functioneaza indiferent unde este ea realizata: in clasa de baza sau in clasa derivata
Alegerea intre compozitie si mostenire • Compozitia se alege atunci cand interfata clasei de baza nu se doreste a fi
expusă in clasa derivata • Compozitia se face, de obicei, prin agregare private • Mostenirea se foloseste atunci cand interfata clasei de baza se doreste preluată
și expusă de clasa derivata
• Protected: functioneaza ca si private din afara ierarhiei • Upcast: obiectele din tipul clasei derivate sunt in acelasi timp si din tipul clasei
de baza
final • itemii final: nu pot fi schimbate ( de exemplu, intr-o clasă derivata) • Datele final:
– Constante la compilare care nu se schimba ulterior – Valori initializate la runtime care nu se doreste sa fie schimbate – Static final: au o singură locatie de stocare a datei
• Final aplicat la o referinta: face referinta constantă, valoarea obiectului poate fi modificata
• Blank final: campuri declarate final care nu sunt initializate -> ele trebuie initializate inainte de utilzare
• Argumente final: în metodă nu se poate schimba valoarea către care arată referinta
• Metode final: nu pot fi schimbate prin mostenire • Metodele final sunt tratate inline de către compilator • Clase final: se inhibă mostenirea din clasa respectivă
Cluj-Napoca - 12 Octombrie 2015
Mecanismul upcast • Asocierea dintre numele metodei si corpul metodei – legare (binding) • Early binding: atunci cand legarea se face la compilare • Late binding: atunci cand legarea se face la executie, exact inainte de
executia efectiva a metodei • Late binding = dynamic binding sau runtime binding • Late binding: necesită un mecanism pentru identificarea tipului la
executie (RTTI) – pentru a se identifica in mod corect corpul metodei care trebuie apelat
• In Java se utilizeaza late binding pentru orice apel de metodă, cu exceptia metodelor static si final (private e implicit final pt ca o metoda private nu poate fi mostenita)
• De ce e nevoie să declarăm o metodă final? Pentru a inhiba late binding (creste eficienta la executie)
• Campurile si elementele static sunt rezolvate la compilare • Legarea constructorilor este realizata la compilare
Cluj-Napoca - 12 Octombrie 2015
Downcast • Downcast: operația inversă upcast – nu este o operație garantată, in
sensul in care nu stim exact clasa derivată către care se face downcast • Downcast trebuie realizat explicit de catre programator • Java verifică orice conversie (cast), si daca nu se poate realiza se
aruncă o exceptie de tipul ClassCastException
Cluj-Napoca - 12 Octombrie 2015
Ordinea de apelare a constructorilor • In cazul obiectelor complexe (cu moștenire), ordinea de apelare
a constructorilor este: – Se apeleaza constructorul clasei de baza. Apelul este recursiv, până
la vârful ierarhiei (constructorul tipului din vârf este apelat primul) – Se initializează membrii clasei in ordinea declarării acestora – Se apelează corpul constructorului clasei derivate
• Ce se intamplă dacă in constructor se apelează o metodă presupusă a se lega dinamic? – In constructor se apeleaza exclusiv metoda suprascrisă (cea din
clasa cu constructorul – legarea este de tip early)
• Covariant return types: – O metodă suprascrisă dintr-o clasă derivată poate returna un tip
derivat dintr-un tip returnat de metoda din clasa de baza (care este suprascrisă)
Cluj-Napoca - 12 Octombrie 2015
Cluj-Napoca - 14 Octombrie 2015
Limbaje de programare – curs 4 - - Informatică Economică, an III –
Gheorghe Cosmin Silaghi
Interfete
Cluj-Napoca - 14 Octombrie 2015
Cuprins
• Clase abstracte • Interfete • Design patternul Strategy si Adapter • Design parternul Factory
Clase abstracte • Rolul clasei Instrument (varful ierarhiei): să creeze o interfață comună
claselor derivate (metoda play din Instrument este “dummy”) • => obiectele din clasa Instrument nu au sens (dpdv logic) • => clasa Instrument: clasă abstractă • Pentru a evita astfel de erori la executie (crearea de obiecte dintr-un
astfel de tip) există un mecanism prin care se declară clasele abstracte (si care se verifică la compilare): cuvantul cheie abstract
• Clasă abstractă: are cel putin o metodă abstractă (metodă declarată abstract si care nu are corp)
• Se generează eroare la compilare dacă se incearcă crearea unui obiect dintr-o clasă abstractă
• La mostenire dintr-o clasă abstractă, metoda abstractă trebuie suprascrisă, altfel clasa derivată devine si ea abstractă
Cluj-Napoca - 14 Octombrie 2015
Conceptul de Interfață • In clasa abstractă: se furnizează o parte din interfață iar implementarea
acesteia este lăsată pe seama claselor derivate • Cuvantul cheie interface: produce o clasă abstractă fără nici o
implementare de metode • Orice cod care utilizeaza o anume interfață va sti ce metode se pot
apela (si doar atât) • Interfetele permit realizarea “moștenirii multiple” • Interfetele pot contine campuri: acestea sunt implicit static si final • Implementarea unei interfețe: cuvântul cheie implements
Cluj-Napoca - 14 Octombrie 2015
Design patternul Strategy • Crearea unei metode care sa aibă comportament diferit in functie de
tipul argumentului care se prezinta la intrare. – Metoda contine o parte fixa care este apelata de fiecare data si o
parte care variază (strategia) • In cazul in care nu se utilizează interfetele, dacă dorim să aplicăm
metoda (strategia) unui obiect dintr-o clasă care nu face parte din ierarhie, nu se poate
• => in exemplul Apply si Procesor, exista o cuplare foarte puternica intre metoda Apply.proces si clasa Procesor, astfel incat aceasta metoda nu poate fi aplicata decat obiectelor din ierarhia Procesor, si nicidecum altor obiecte din alte ierarhii
• Procesor se creaza ca si o interfata, iar clasele care doresc sa faca parte din strategie vor implementa interfata scrisa
Cluj-Napoca - 14 Octombrie 2015
Design patternul Adapter • Ce se intampla in cazul in care dorim sa utilizam in strategie o
clasa importata dintr-o bibliotecă? • Design patternul Adapter: se scrie cod care preia la intrare
interfata existenta si care sa produca interfata de care este nevoie in program
• Prin decuplarea interfetei de implementare se permite ca o interfata sa fie aplicata mai multor implementari, deci codul devine mult mai facil de reutilizat
Cluj-Napoca - 14 Octombrie 2015
Cluj-Napoca - 14 Octombrie 2015
Mosternirea multipla • In Java se poate extinde o singura clasă si se pot implementa oricate clase • Rolul interfetelor: sa se poata face upcast la mai mult decat o clasa de baza • Daca se poate crea o clasa de baza fara definitii de metode si variabile
membre, se recomanda sa se creeze interfete in locul claselor abstracte • Interfetele se pot combina (se extinde interfetele la fel ca si clasele) • Coliziunea numelor la implementarea mai multor interfete (daca interfetele
de baza au acelasi nume de metoda cu semnaturi diferite): este o problema daca metodele difera doar prin tip de return => eroare la compilare
• Campurile care sunt inserate intr-o interfata devin in mod automat static si final => reprezinta un mod convenabil pentru a defini constante (similar cu enum)
• Campurile definite in interfete nu pot fi blank finals, ele trebuie initializate la definire
Cluj-Napoca - 14 Octombrie 2015
Design patternul FactoryMethod • Rolul unei interfete: sa se permita implementari multiple pentru diverse
clase • Design patternul Factory: in loc sa se apeleze un constructor in mod
direct, pentru crearea unui obiect se apeleaza o metoda de creere a obiectului dintr-o clasa Factory. Clasa Factory implementeaza o interfata care specifica metoda de creere
• Astfel, se poate schimba la runtime o implementare a unei functionalitati cu alta
Cluj-Napoca - 14 Octombrie 2015
Cluj-Napoca - 14 Octombrie 2015
Cluj-Napoca - 21 Octombrie 2015
Limbaje de programare – curs 6 - - Informatică Economică, an III –
Gheorghe Cosmin Silaghi
Claseinterioare
Inner classes • Se plaseaza clase in interiorul altor clase • Inner classes reprezinta un concept diferit de compozitie • De obicei, clasa exterioara are o metoda care returneaza un obiect din clasa inner • Tipul obiectului din clasa interioara se specifica precum: OuterClass.InnerClass • Obiectul clasei interioare are un link (referinta) catre obiectul clasei exterioare care l-a
creat!!! • Obiectul clasei interioare poate accesa membrii obiectului clasei exterioare fara ca sa
fie nevoie de calificare (dreptul de a accesa este asupra tuturor obiectelor membre ale clasei exterioare)
• Pentru a se obtine referinta la obiectul clasei exterioare (din obiectul clasei inner) se utilizeaza: OuterType.this
• Pentru a crea un obiect din clasa inner pornind de la un obiect din clasa outer se poate utiliza: obiectOuter.new
• Clasele inner sunt potrivite pentru a implementa interfete: se realizeaza ascunderea implementarii
Cluj-Napoca - 21 Octombrie 2015
Clase interioare (II)
• Clasele interioare pot fi create intr-o metoda sau domeniu de vizibilitate deoarece: – Se implementeaza o interfata, deci se poate crea si returna o referinta la
aceasta (upcast) – Se rezolva o problema complicata si dorim sa creem o clasa care sa ne ajute
la rezolvarea problemei, dar nu dorim ca aceasta sa fie publica
• Clasa interioara poate fi accesata doar din interiorul metodei (sau domeniului de vizibilitate) unde a fost definita
Cluj-Napoca - 21 Octombrie 2015
Clase interioare anonime • Sunt clase interioare fara nume (clase create direct la momentul utilizarii
lor) • ; finalizeaza constructia instructiunii care contine definitia clasei anonime • Campurile din clasele anonime pot fi initializate cu valori din afara (din
domeniul unde se creaza clasa) • Daca intr-o clasa anonima se doreste a fi utilizat un argument (sau o
valoare) definita in afara acesteia, atunci referinta acesteia trebuie sa fie final
• Clasele anonime nu pot avea constructor, dar initializarile se pot realiza in blocul non-static de initializare
• Clasele interioare pot fi create static (nested classes) daca nu se doreste utilizarea referintei obiectului exterior in interiorul clasei inner
• Clasele interioare parte a unei interfete devin automat static public. Rol: crearea de cod comun care sa fie utilizat de toate implementarile interfetei
• Oricat de adanca este imbricarea claselor nested, acestea pot accesa obiectele membre din clasele exterioare, indiferent de nivelul de imbricare
Cluj-Napoca - 21 Octombrie 2015
De ce clase inner?
• Fiecare clasa inner poate in mod independent sa mosteneasca de la o alta implementare. Deci o clasa inner nu este limitata de faptul ca clasa exterioara mosteneste sau nu din implementare
• Clasa interioara poate avea instante multiple, fiecare cu propria stare, care este independenta de starea obiectului din clasa exterioara
• O singura clasa exterioara poate avea mai multe clase interioare fiecare implementand aceasi interfata sau mostenind din aceasi clasa in mai multe feluri
• La momentul creerii obiectului din clasa inner, acesta nu este legat de creerea obiectului din clasa outer
• Inner class este o clasa total diferita de clasa exterioara, nu exista confuzie de tipul is-a
Cluj-Napoca - 21 Octombrie 2015
Closures & callbacks
• Closure: un obiect apelabil care retine informatie despre domeniul de vizibilitate in care a fost creat (are access la variabilele din domeniul de vizibilitate unde a fost creat)
• => clasa interioara este un closure (deoarece are o referinta catre obiectul exterior si poate sa acceseze inclusiv membrii privati ai clasei exterioare)
• Callback: un obiect primeste o informatie care va permite sa apelam obiectul initial la un moment ulterior de timp
• Callback se implementeaza cu clase interioare
• Clasa de tip Closure furnizeaza o poartă în intriorul clasei exteriore (dar intr-un mod safe – nu se necesită ca sa transformam accesul la metodele acestei clase)
• De ce callbacks? La executie, se poate schimba metoda care este apelată, in mod dinamic
Cluj-Napoca - 21 Octombrie 2015
Control frameworks • Application framework: un set de clase proiectate sa rezolve un tip
anume de problemă (design patternul Template Method) • Pentru aplicarea application framework se mostenesc din clasele de
baza si se schimba implementarea prin overriding • Codul suprascris este cel care customizeaza solutia la cazul particular • Template Method: contine structura de baza a algoritmului, iar partile
specifice sunt apeluri la metode care pot fi override • Astfel, se separa partile neschimbate ale algoritmului de cele flexibile • Control framework: un tip particular de application framework prin care
sistemul raspunde la evenimentele generate (sistem event-driven) – de exemplu GUIs
• In implementarea Control framework, inner class sunt utilizate pentru a exprima diversele actiuni (metoda action)
Cluj-Napoca - 21 Octombrie 2015
Mostenire din clase inner • La mostenire dintr-o clasa inner, trebuie furnizat la constructia obiectului un
obiect din clasa inner, pentru a se permite construirea sub-obiectului cl. baza ( enclosingClassReference.super() )
• Clasele locale unui domeniu de vizibilitate au access la toate variabilele domeniului respectiv (inclusiv cele final), insa aceste clase nu au specificator de access
Cluj-Napoca - 21 Octombrie 2015
Cluj-Napoca - 26 Octombrie 2015
Limbaje de programare – curs 7 - - Informatică Economică, an III –
Gheorghe Cosmin Silaghi
Colec4i,Excep4i
Cluj-Napoca - 26 Octombrie 2015
Introducere
• Sirurile de obiecte (arrays): reprezinta cel mai eficient mod pentru a păstra obiecte.
• Neajuns: au dimensiunea fixata la compilare
• Java.util: clase container: List, Set, Queue, Map
• Pre-java SE5: containerele java pot memora orice tip de obiecte, deci pot apărea erori
• De exemplu: ArrayList are metodele add si get definire utilizand clasa Object
• Erorile la regasirea obiectelor din container pot sa fie identificate doar la executie (ClassCastException)
Containere generice • TipContainer<TipDeBaza> • In container se pot păstra doar obiecte din tipul de bază • Se obtine o eroare la compilare daca se incearcă stocarea unui
obiect dintr-un alt tip • Nu mai este necesară operatia de cast (conversie) la regasirea
obiectelor
• Operatii de efectuat la utilizarea containerelor 1. Definirea obiectului de tip container 2. Inserarea de obiecte in container (de ex. Metoda add) 3. Regasirea obiectelor (de ex. Metoda get)
– Daca sunt containere generice nu mai este nevoie de cast – La containere pre-Java SE5, trebuie conversie
Cluj-Napoca - 26 Octombrie 2015
Tipuri de containere Java • Colectii: memoreaza o secventa de elemente individuale, impreuna
cu una sau mai multe reguli aplicate acestora – List: memoreaza obiectele in ordinea in care au fost inserate – Set: nu se permit obiecte duplicat – Queue: regaseste elementele după ordinea furnizata de regula de insiruire
• Map: reprezinta grupuri de perechi de tip (cheie, valoare). – Intr-un Map se regaseaste un obiect (valoarea) prin furnizarea cheii
• Collection, List, Set, Queue si Map reprezinta interfete
• List<Apple> apples = new ArrayList<Apple>(); • List<Apple> apples = new LinkedList<Apple>();
• In colectii se pot adauga grupuri de elemente • Collection.Arrays.asList() Collection.addAll()
Cluj-Napoca - 26 Octombrie 2015
Ierarhia de clase colectii
Cluj-Napoca - 26 Octombrie 2015
Lucrul cu containerele • Tiparirea acestora: metoda toString • sortare: metoda sort
Liste: 2 tipuri de liste • ArrayList: lista implementata cu un sir. Permite operatii rapide pentru
access random la elemente. Operatiile de inserare si stergere de la mijlocul listei sunt costisitoare
• LinkedList: lista implementata cu lista simplu inlantuita. Permite operatii rapide de insertie si stergere de la mijlocul listei, insa operatiile de regasirea aleatoare sunt costisitoare
Cluj-Napoca - 26 Octombrie 2015
Iteratori • Este un design pattern • Un obiect de tip iterator este asociat unei colectii si permite regasirea
ordonata a obiectelor din colectia respectiva • Metoda iterator() a unei colectii • Metoda next() a obiectului iterator: produce urmatorul element din
colectie • Metoda hasNext(): interogheaza daca mai sunt elemente neiterate • Metoda remove(): sterge ultimul element iterat din colectie
• Iteratorii pot produce elementele colectiei doar intr-o singura directie • ListIterator: furnizat doar de interfata List, poate parcurge elementele
colectiei in ambele directii
Cluj-Napoca - 26 Octombrie 2015
Exceptii (i) • Nu toate erorile pot fi prinse la scrierea programului (la compilare) • Restul problemelor trebuie rezolvate la execuție print-un mecanism prin care
sa se ofere programului client informatia necesara rezolvarii situației • => exception handling: singurul mecanism Java pentru tratarea erorilor
• Conceptul de exceptie: in domeniul de vizibilitate unde apare eroarea de obicei nu stim cum sa tratam eroarea, insa stim ca nu putem să continuăm cu eroarea, astfel că transmitem eroarea spre rezolvare la un domeniu de vizibilitate exterior
• Exception condition: eroarea apărută (de exemplu impărțire la 0) • La apariția unei erori:
– Se crează un obiect de tip exceptie (pe heap, cu new) – Firul de executie curent este intrerupt si referinta la obiectul exceptie este transmisă in afara
contextului curent – Mecanismul de exception handling caută un context potrivit pentru reluarea executiei
programului – Handlerul de exceptie: locul de unde se reia executia programului, recupereaza programul de
la eroarea aparuta
Cluj-Napoca - 26 Octombrie 2015
Exceptii (ii) • Aruncarea unei exceptii if (t==null)
throw new NullPointerException();
• Obiectele de tip exceptie pot fi construite cu argumente transmise • La throw se poate arunca orice obiect dintr-un tip care extind clasa
Throwable (clasa radacina a ierarhiei exceptiilor)
• Conceptul de tranzactie: totul sau nimic • Premisa fundamentala a tranzactiilor: existenta conceptului de exceptie
Cluj-Napoca - 26 Octombrie 2015
Guarded regions try { // codul care este susceptibil sa genereze exceptie } catch (Type1 tp1) { // exceptii de tipul Type1 } catch (Type2 tp2) { // exceptii de tipul Type2 } … finally { // cod care se executa indiferent de tipul de exceptie aruncat (sau nu) }
• Try – catch functioneaza ca un switch pe tipul de exceptie • 2 modalitati de tratare a erorilor
– Termination: eroarea este aruncata – Resumption: se insereaza cod try – catch pt rezolvarea erorii
Cluj-Napoca - 26 Octombrie 2015
Crearea propriilor exceptii • Mostenire din clasa Exception • La afisari la o eroare se recomanda utilizarea System.err in loc
de System.out • printStackTrace(..) : se afiseaza secventa de metode apelate
pentru a se ajunge la exceptie • getMessage() : mostenit de la Throwable, e similar cu toString
pentru erori
• Logging: – Urmarirea executiei programului pentru a putea rezolva mai usor erorile – java.util.logging – Se creaza un obiect de tip Logger – Se pot loga mesaje de tip fine, info, severe, warning, etc.
Cluj-Napoca - 26 Octombrie 2015
Specificarea exceptiei • La o metoda, prin throws se indica tipul erorilor care pot sa fie aruncate de
către metoda respectiva • Erorile de tip RuntimeException nu trebuiesc specificate prin throws • Compilatorul forteaza programatorul să specifice exceptiile
– Daca intr-o functie este posibil să apara o exceptie si programatorul nu o specifica prin throws, atunci apare eroare la compilare
– Erorile verificate si enforced la compilare: checked exceptions
• Prinderea oricarei exceptii: – catch (Exception e) {.. }
• StackTrace: – printStackTrace, getStackTrace
• Rearuncarea unei exceptii: – In catch se face throw
Cluj-Napoca - 26 Octombrie 2015
Inlantuirea exceptiilor • La prinderea unei exceptii si aruncarea unei alte exceptii, se doreste
pastrarea lantului exceptiilor care apar • Subclasele Throwable pot sa utilizeze cauza erorii ca si argument in
constructor • Se poate folosi clauza la constructor doar la clasele de tip Error,
Exception sau RuntimeException • La celelalte tipuri de erori, se poate utiliza initCause
Cluj-Napoca - 26 Octombrie 2015
Ierarhia exceptiilor Java • Clasa Throwable: orice este mostenit din throwable poate fi aruncat cu
throw • 2 tipuri de obiecte Throwable: Error and Exception • Exceptiile java mostenesc din clasa Exception • Numele exceptiei este sugestiv pentru cauza aparitiei exceptiei • RuntimeException: sunt aruncate in mod automat de catre java la
momentul aparitiei lor – unchecked exceptions • De obicei, acestea indica buguri si nu trebuie prinse cu try-catch
Cluj-Napoca - 26 Octombrie 2015
Exceptii pierdute • Exista o clauza finally fara catch • Sau in finally se face return • Programatorul nu are nici o indicatie despre exceptia pierduta
Restrictii la exceptii: • Cand se suprascrie o metoda, se pot arunca doar exceptiile de tipul
specificat in metoda din clasa de baza • Atentie la exceptii in constructori: constructorii trebuie sa isi incheie cu
success executia pentru a aduce obiectele intr-o stare sigura
• Exception matching: se face potrivire pe cea mai apropiata clauza catch care potriveste cu tipul exceptiei
Cluj-Napoca - 26 Octombrie 2015
Guidelines • Tratati exceptiile la domeniul de vizibilitate potrivit (nu prindeti exceptii decat
daca stiti ce sa faceti cu ele) • La rezolvare, de obicei se rezolva problema exceptiei si se reia executia
codului care a generat exceptia sau • Se transmite executia la un nivel superior fara reluarea codului sau • Se poate calcula un rezultat alternativ celui produs de codul care a generat
exceptia sau • Se poate executa tot ce e posibil in domeniul curent si se arunca aceasi
exceptie la un nivel superior sau • Se poate executa tot ce e posibil in domeniul curent si se arunca o alta
exceptie la nivel superior sau • Se poate termina programul • Sa facem programele nostre simple • Sa facem programele nostre safe prin debugging
Cluj-Napoca - 26 Octombrie 2015
Cluj-Napoca - 28 Octombrie 2015
Limbaje de programare – curs 8 - Informatică Economică, an III –
Gheorghe Cosmin Silaghi
I/OinJava
Sistemul de I/O intr-un limbaj de programare
• Sistemul de I/O intr-un limbaj de programare trebuie să fie capabil să trateze – Surse diferite de dispozitive de I/O (fisiere, consola, conexiuni de retea
etc) – Tipuri diferite de access la surse (access secvential, access random,
access buffered) – Tipuri diferite de lucru cu sursa (binar, la nivel de caracter, la nivel de
linie, la nivel de cuvant)
Cluj-Napoca - 28 Octombrie 2015
Clasa File • Reprezinta un nume a unui fisier sau unui set de fisiere dintr-un
director • Metoda list() -> produce un sir de String care reprezinta fisierele
referite de obiectul de tip File • List poate fi invocata utilizand un Directory Filter, pentru a returna doar
acele fisiere pentru care numele respecta un pattern • Interfata FilenameFilter: metoda accept primeste la intrare obiectul de
tip File si stringul pentru comparare. Metoda list din File apeleaza metoda accept pentru fiecare fisier din File, iar acesta este inserat in lista doar daca accept furnizeaza true
• Obiectul File poate fi utilizat ca sa creem/stergem/redenumim un director/fisier sau un director/fisier cu o intreaga cale
• File poate fi utilizat ca sa citim informatiile referitoare la un fisier/director
Cluj-Napoca - 28 Octombrie 2015
Input si Output • Pentru intrare: clasele InputStream si Reader cu metoda read • Pentru iesire: clasele OutputStream si Writer cu metoda write • Read si write lucreaza pe octeti (sau siruri de octeti) • Toate clasele de I/O sunt derivate din acestea • La realizarea efectiva de I/O programatorii creaza insuruiri de obiecte
din clasele de I/O (design patternul Decorator)
Cluj-Napoca - 28 Octombrie 2015
Tipuri de InputStream
• ByteArrayInputStream: permite ca un buffer de memorie sa fie utilizat ca si un InputStream (din buffer se extrag octeti)
• StringBufferInputStream: converteste un String intr-un InputStream • FileInputStream: sursa de intrare e un fisier. Se furnizeaza la
construirea obiectului fie un String fie un File • PipedInputStream: este asociat cu un PipedOutputStream (care este
furnizat la construirea obiectului). Implementeaza conceptul de Pipe • SequenceInputStream: converteste unul sau mai multe InputStream
intr-un singur obiect de tip InputStream (la construire se furnizeaza fie un InputStream, fie un Enumerator de obiecte InputStream)
• FilterInputStream: clasa abstracta, interfata pentru decoratorii care furnizeaza tipuri particulare de citire
Cluj-Napoca - 28 Octombrie 2015
Tipuri de OutputStream • ByteArrayOutputStream: creaza un buffer de memorie (octeti). Datele scrise
sunt trimise in acest buffer • FileOutputStream: iesire intr-un fisier. Se construieste obiectul pe baza unui
String sau a unui File • PipedOutputStream: in conjunctie cu PipedInputStream. Pentru conceptul de
Pipe • FilterOutputStream: pentru iesire formatata, se implementeaza functionalitati
de scriere
Cluj-Napoca - 28 Octombrie 2015
Design patternul Decorator
• Decoratorul trebuie sa aiba aceasi interfata cu obiectele decorate. • Decoratorul poate să extinda interfata acestor obiecte. • Clasele Filter sunt radacina abstracta a claselor de decorator
Cluj-Napoca - 28 Octombrie 2015
Tipuri de FilterInputStream • DataInputStream: se pot citi tipuri primitive (int, char, long etc) • Buffered InputStream: citire din buffer, se previne accesul la dispozitivul
fizic la fiecare operatie de read • LineNumberInputStream: tine evidenta numarului de linie citit (cu
getLineNumber) • PushbackInputStream: se poate pune inapoi in stream ultimul octet citit
Cluj-Napoca - 28 Octombrie 2015
Tipuri de FilterOutputStream • DataOutputStream: se pot scrie primitive • PrintStream: folosit pentru formatarea afisarii (metodele print si
println) • BufferedOutputStream: pentru afisare optimizata prin buffer (se evita
accesul la dispozitivul fizic la fiecare afisare)
Cluj-Napoca - 28 Octombrie 2015
Reader si Writer • Adauga functionalitate pentru I/O la nivel de caracter sau Unicode • Clasele sunt adaugate in ierarhia InputStream si OutputStream deci nu
se inlocuieste aceasta ierarhie • Clase adapter: InputStreamReader si OutputStreamWriter • Motivul pentru care au fost create: sa se permita internationalizarea
(Unicode lucreaza cu caractere pe 16 biti) • Recomandare: sa se utilizeze clase de tip Reader si Writer ori de cate
ori e posibil • La citiri specifice la nivel de octet, sa se utilizeze InputStream si
OutputStream
Cluj-Napoca - 28 Octombrie 2015
Corespondenta de clase
Cluj-Napoca - 28 Octombrie 2015
Clasede(pInputStream/OutputStream
Clasede(pReader/Writer
InputStream ReadercuadapterulInputStreamReader
OutputStream WritercuadapterulOutputStreamWriter
FileInputStream/FileOutputStream FileReader/FileWriter
StringBufferedInputStream StringReader/StringWriter
ByteArrayInputStream/ByteArrayOutputStream
CharArrayReader/CharArrayWriter
PipedInputStream/PipedOutputStream PipedReader/PipedWriter
FilterInputStream/FilterOutputStream FilterReader/FilterWriter
BufferedInputStream/BufferedOutputStream
BufferedReader/BufferedWriter
PrintStream PrintWriter
StreamTokenizer StreamTokenizer(areconstructorcuReader)
PushbackInputStream PushbackReader
RandomAccessFile • Fisiere cu inregistrări cu dimensiune cunoscută – se poate utiliza functia
seek pentru pozitionare in fisier • Aceasta clasa nu face parte din ierarhiile InputStream sau
OutputStream • Metoda getFilePointer() : returneaza pozitia in fisier • seek() : pentru a muta pointerul de fisier • Length() : lungimea maxima a fisierului • Incepand cu JDK 1.4: apar fisierele memory-mapped
Cluj-Napoca-28Octombrie2015
Realizarea fisierelor comprimate
• Java furnizeaza clase pentru compresie si decompresie, in ierarhia InputStream si OutputStream
• CheckedInputStream: GetCheckSum() produce checksum • CheckedOutputStream: GetCheckSum() produce checksum • DeflaterOutputStream: varful ierarhiei de clase pentru compresie • ZipOutputStream: compresie Zip • GZIPOutputStream: compresie GZIP • InflaterInputStream: varful ierarhiei de clase pentru decompresie • ZipInputStream : decompresie Zip • GZIPInputStream : decompresie GZIP • ZipFile / ZipEntry : pentru a manipula fisiere de tip zip
Cluj-Napoca-28Octombrie2015
Fisiere jar • JAR: Java ARchive: colecteza fisiere intr-o singura arhiva pentru pentru
a putea fi transmise in Internet • Fisierul JAR contine fisierele arhivate + fisier manifest • JDK contine utilitarul jar pentru crearea de arhive jar • De obicei un fisier jar contine bytecode (fisiere .class)
Cluj-Napoca-28Octombrie2015
serializare • Pastrarea obiectelor dincolo de executia programelor • Astfel obiectele pot fi recuperate si executia restartata de la punctul unde a fost
oprita anterior • Orice obiect dintr-o clasă care implementeaza Serializable poate fi convertit in sir
de octeti si apoi restaurat • Persistentă: durata de viata a unui obiect exista dincolo de executia unui program • Pentru realizarea persistentei, obiectele trebuie serializate / deserializate in mod
explicit (lightweight persistence) • Pentru serializare, se crează un obiect dintr-un tip OutputStream, acesta este
“wrap” in interiorul unui ObjectOutputStream si se utilizeaza metoda writeObject • Pentru deserializare avem ObjectInputStream si readObject -> se recupereaza un
Object si trebuie facut downcast • Serializarea salveaza intreg webul de obiecte din spatele obiectului serializat • Tipul unui obiect deserializat: getClass
Cluj-Napoca-28Octombrie2015
Externalize • Ce se intampla daca dorim ca parti din obiect sa nu fie serializate? • Sau dorim să recreem subobiecte de la zero? • Interfata Externalizable: extinde interfata Serializable • 2 metode noi: writeExternal, readExternal • Aceste metode sunt apelate automat la serializare / deserializare si contin
cod suplimentar care se executa la aceste operatii • La obiectele deserializate cu Externalizable, obiectele sunt construite
obisnuit (cu default constructor) si apoi se apeleaza metoda readExternal • La obiectele Externalizable, subobiectele componente trebuie serializate
manual (in writeExternal) iar la deserializare, ele trebuie recuperate de pe disc
• La mostenire dintr-o clasa Externalizable, se apeleaza writeExternal si readExternal a clasei de baza pentru a se asigura serializare / deserializare corecta
Cluj-Napoca-28Octombrie2015
Evitarea serializarii anumitor componente ale obiectelor
• Prima metoda: utilizarea Externalizable • Metoda 2-a: cuvantul cheie transient: indica faptul acel camp marcat cu
transient nu va fi serializat ca si parte a procesului automat de serializare
• Metoda 3-a: se adauga la clase metodele writeObject si readObject in care se furnizeaza codul programatorului pentru serializare – Aceste metode sunt private si sunt apelate automat de catre writeObject si readObject
a claselor ObjectOutputStream si ObjectInputStream
Cluj-Napoca-28Octombrie2015
Cluj-Napoca - 2 Noiembrie 2015
Limbaje de programare – curs 9 - Informatică Economică, an III –
Gheorghe Cosmin Silaghi
RTTI
RTTI • Run-Time Type Identification • Descoperirea tipului la executie si utilizarea acestuia • 2 tipuri de TTI:
– Traditional – la compilare – Reflection: - la executie !!!
• Upcast: necesită realizarea automata a RTTI pentru invocarea automată (polimorfică) a metodei suprascrise
• Prin RTTI se poate identifica tipul exact al unui obiect la executie (limbajul de programare are metode pentru a realiza acest lucru)
Cluj-Napoca - 2 Noiembrie 2015
Obiectul Class • Java realizează RTTI prin intermediul obiectului Class • Acesta contine informatie referitoare la tip, informatie care poate fi
interogată • Pentru fiecare clasă pe care o avem in program, există un obiect Class
asociat • La compilarea unei noi clase, acest obiect este creat si salvat in
fisierul .class • La crearea unui obiect dintr-o clasă, JVM utilizează un subsistem numit class
loader • Toate clasele sunt incarcate in mod dinamic de către JVM la prima utilizare
a acestora (anume cand se face prima referinta la un membru static al clasei)
• La incarcarea unei clase, se verifică daca obiectul Class al tipului respectiv este incarcat, daca nu, se identifică fisierul .class pe disc, si octetii acestuia sunt verificati inainte să fie incarcati
Cluj-Napoca - 2 Noiembrie 2015
Obiectul Class • Metoda forName(“…”) : returneaza o referinta catre obiectul Class
aferent unui tip – Solicită incarcarea fisierului .class daca acesta nu e deja incarcat de class
loader
• Metoda Object.getClass(): returneaza obiectul de tip Class aferent unui tip deja incarcat
• Metode ale obiectului Class: getName, getSimpleName, getCanonicalName, isInterface, getInterfaces, getSuperclass,
Cluj-Napoca - 2 Noiembrie 2015
class literal
• Referinta la obiectul de tip class poate fi obtinut si astfel: NumeTip.class
• Este safe: poate fi verificat la compile time • TYPE: pentru tipurile wrapper de primitive
– boolean.class === Boolean.TYPE
• Crearea unei referinte prin .class nu initializează obiectul de tip Class corespunzator
• Pregatirea unui obiect pentru utilizare: in 3 moduri – Incarcarea clasei, realizata de class loader, se gaseste bytecodul pe disc si se crează
obiectul Class corespunzator tipului – Linking: se aloca spatiu de stocare pentru membrii statici si se rezolva toate referintele
realizate de clasă către alte clase – Initializare: se executia intializatorii statici si blocurile statice de initializare. Initializarea
este intarziată până la prima referinta la o metodă statică sau un camp non-static
• Initializarea obiectului Class este amanata atata timp cât este posibil
Cluj-Napoca - 2 Noiembrie 2015
Generic class reference • Class<tip> : permite salvarea de referinte doar la obiectul Class a tipului
respectiv
• Atentie: Class<Interger> nu e subclasa a lui Class<Number> cu toate ca Integer e derivata din Number!!!
• Class<?> : se permite orice tip (? – wildcard) • Class<? Extends Tip> : se permite orice subtip a lui Tip
• Conversie de tip: metoda obiectClass.cast(referinta)
• Conversia in mod clasic (..)obiect nu apeleaza RTTI => nevoia pt instanceof
if (x instanceof Dog) => necesar pt a se evita ClassCastException ((Dog)x).bark();
Cluj-Napoca - 2 Noiembrie 2015
Compararea obiectelor de tip Class
• Este diferenta intre instanceof / isInstance si compararea obiectelor de tip Class cu == sau equals – La instanceOf / inInstance se tine cont de relatiile de mostenire – La comparare cu == sau equals nu se tine cont de relatiile de mostenire
Cluj-Napoca - 2 Noiembrie 2015
Reflection • Cum lucram cu obiecte a caror clase nu sunt disponibile la compilare? • Java.lang.reflect • Clasele Field, Method, Constructor • getFields, getMethods and getConstructors
Cluj-Napoca - 2 Noiembrie 2015
Desing patternul Proxy • Proxy: Un obiect substitut, transmis in locul unui obiect real, pentru a
furniza prelucrari aditionale inainte de a transmite operatiile catre obiectul real
• Dynamic proxy: se creaza obiectul proxy dinamic si se trateaza apelurile catre metodele proxied in mod dinamic
Cluj-Napoca - 2 Noiembrie 2015
Cluj-Napoca - 4 Noiembrie 2015
Concurenta in Java – curs 10 Noțiuni de bază
- Informatică Economică, an III –
Gheorghe Cosmin Silaghi
Cluj-Napoca - 4 Noiembrie 2015
Introducere in programarea concurenta
• Programele scrise pana acuma: secventiale • Programare concurenta: mai multe fire de executie care ruleaza in
paralel • Exemple de utilizare a modelului concurent de executie in Java:
– Sistemul web clasic – JSP – Swing si SWT au mecanisme pentru suport concurenta
• Motive pentru a realiza programe concurente – Executie mai rapida – in conditiile programarii multiprocesor – Imbunatatirea code design
• Concurenta induce un cost: complexitate sporita a programelor
Cluj-Napoca - 4 Noiembrie 2015
Executia mai rapida a programelor
• Tendinta curenta: numar mai mare de core-uri, in conditiile plafonarii vitezei chipurilor • Prin distribuirea takurilor pe procesoare se creste throughput • Chiar in conditiile single core, programele concurente se pot executa mai rapid
(datorita situatiilor blocking) • Daca un task (sau thread) nu poate continua (de ex. datorita operatiilor de I/O), se
spune ca acel task e blocat. • event-driven programming: realizarea de interfete grafice responsive, in conditiile in
care prelucrarile asociate unor evenimente dureaza
• Un proces este un program de sine statator cu propriul spatiu de adrese • Un sistem de operare multi-tasking poate sa ruleze mai multe procese la un moment
dat (datorita schimbarii periodice a CPU de la un proces la altul) – implementarea concurentei la nivel de SO
• Implementarea concurentei la nivel de mediu de programare: presupune existenta unor resurse comune si coordonarea utilizarii acestor resurse de catre threaduri. Mai mult, procesele pot comunica intre ele
Tipuri de sisteme paralele
Shared-memory Distributed-memory
Cluj-Napoca - 4 Noiembrie 2015
Cluj-Napoca - 4 Noiembrie 2015
Abordari ale concurentei in LP (I)
• Taskurile concurente sa fie izolate unele de altele (fiecare functie concurenta nu produce side effects) – modelul distributed memory – ex. Erlang (Erricson)
• C/C++: fork: se creaza procese separate gestionate de catre SO • Java: in cadrul unui singur proces gestionat de catre SO, se creaza mai
multe taskuri prin threading • C/C++ / Java – modelul shared memory
Abordari ale concurentei (II)
• Java threading este preemtive: mecanismul de scheduling furnizeaza o felie de timp procesor fiecarui thread, prin intreruperea periodica a threadului care se executa si schimbarea contextului de executie catre un alt thread
• Intr-un sistem multithreading cooperativ fiecare thread isi lasa controlul catre alt thread la un anume moment => programatorul trebuie sa insereze un soi de yield
Cluj-Napoca - 4 Noiembrie 2015
Cluj-Napoca - 4 Noiembrie 2015
Code design
• Unele probleme (precum cele de simulare) sunt concurente prin definitia lor • Chiar daca sistemul pe care programul se executa are un singur CPU, programele
concurente au o claritate mai mare
• Java threading este preemtiv => suport pentru numar limitat de threaduri (de ordinul zecilor) -> poate fi limitativ in anumite situatii
• Cooperative multithreading: nu exista o limita a taskurilor independente care pot rula la un moment dat
• Concurenta este benefica daca se lucreaza cu arhitecturi moderne de tip messaging - sisteme distribuite
• Prin messaging se realizeaz coordonarea proceselor intre ele (fara sa fie nevoie de partajarea de resurse)
Cluj-Napoca - 4 Noiembrie 2015
Threading in Java
• Thread: un flux secvential de executie dintr-un proces • Intr-un sistem multi-threading, un proces poate contine mai multe
threaduri concurente • Programatorul proate programa fiecare dintre aceste threaduri ca si cum ar
avea intreg procesorul la dispozitie
• Pentru a defini un task trebuie implementara interfata Runnable • In general, metoda run a aceste interfete are o bucla care se executa atata
timp cat este necesar
• Fct main are alocat propriul thread. Pt un task nou, trebuie sa se creeze un obiect dintr-o clasa care implementeaza Runnable
Cluj-Napoca - 4 Noiembrie 2015
Terminologie
• In Java exista distinctie intre taskul care este executat si threadul care executa acest task
• Obiectele care implementeaza Runnable sunt taskuri, iar threadurile ajuta la executia acestor taskuri
• Crearea unui thread este o operatie costisitoare (bazata low-level pe conceptul de pthread din C) -> are sens ca sa gestionam threadurile cu grija
• -> distinctia task – thread are sens
Terminologie: • Task: un anume job care trebuie realizat • Thread: mecanismul care executa taskul.
Cluj-Napoca - 4 Noiembrie 2015
Clasa Thread
• Pentru a crea un thread, trebuie furnizat un obiect de tip Runnable in constructorul unui obiect de tip Thread
• Metoda start a clasei Thread realizeaza toate initializarile necesare si apoi apeleaza metoda run a obiectului Runnable agregat. Metoda run este apelata intr-un fir nou de executie
• Mecanismul pentru lansarea threadurilor in executie este non-deterministic (nu putem garanta ordinea in care schedulerul aloca procesorul diverselor taskuri)
• Thread.yield() -> solicita JVM sa dea controlul unui alt thread din programul curent – pentru a solicita invocarea schedulerului
• Garbage collectorul nu va colecta un thread nereferit decat dupa ce acesta isi termina executia propriului run
Cluj-Napoca - 4 Noiembrie 2015
Variatii la crearea taskurilor
• 1. se creaza o clasa care implementeaza Runnable. Un obiect din aceasta clasa e transmis in constructorul unui obiect de tip Thread
• 2. se mosteneste din clasa Thread, si se suprascrie metoda run • 3. se creaza o clasa care implementeaza Runnable. Aceasta clasa
agrega un obiect de tip Thread construit prin new Thread(this) • Atentie: la metodele 2 si 3 taskurile sunt pornite din constructor (cu
start). -> e problematic, threadul isi poate incepe executia inainte ca constructorul sa se termine
• => se prefera varianta 1 si utilizarea executorilor
• Clasele care implementeaza Runnable sau exting Thread pot fi scrise si ca si clase inner (eventual anonime) !!!
Cluj-Napoca - 4 Noiembrie 2015
Executors
• Java furnizeaza un nivel intermediar intr-un client si taskurile pe care acesta le executa. In loc ca clientul sa apeleze taskurile in mod direct, un obiect intermediar (executor) va apela aceste taskuri indirect
• Executors gestioneaza ciclul de viaza a taskurilor asincrone fara sa fie nevoie sa gestionam explicit ciclul de viata a unui obiect Thread
• Se creaza un ExecutorService prin apelarea unei metode specifice a clasei Executors • Metoda shutdown: previne ca alte taskuri sa fie trimise catre executorService spre
executie
• Tipuri de ExecutorService: – FixedThreadPool: fixeaza de la inceput numarul de threaduri utilizate pentru
executia taskurilor. Este o metoda deosebit de eficienta pt ca overheadul cu crearea threadurilor este realizat la crearea obiectului de tip ExecutorService
– CachedThreadPool: permite un numar variabil de threaduri. Va opri crearea de threaduri noi pe masura ce threadurile vechi sunt reciclate
– SingleThreadExecutor este un FixedThreadPool cu un singur thread (de obicei pentru long-lived thread – ex. Treaduri care asculta un socket)
Crearea de threaduri pt Executors
• ThreadFactory: interfata pentru crearea de threaduri la cerere. Threadurile pot fi personalizate (de exemplu, threaduri daemon) – metoda newThread
• Obiecte implementand ThreadFactory pot fi furnizate ca si constructori pentru Executori; executor service-ul rezultat va utiliza acest threadFactory pentru crearea noilor threaduri (cu metoda newThread)
Cluj-Napoca - 4 Noiembrie 2015
Cluj-Napoca - 4 Noiembrie 2015
Returnarea de valori din taskuri
• Interfata Callable: metoda call care trebuie sa returneze o valoare • Obiectele Callable trebuie apelate de metoda submit a unui ExecutorService • Metoda submit produce un obiect de tip Future parametrizat cu tipul
rezultatului specific returnat din task • Obiectul Future poate fi interogat cu metoda isDone() pentru a vedea daca
metoda call a produs rezultatul. • Metoda get() a obiectului Future obtine rezultatul produs de metoda call.
Daca rezultatul nu este disponibil, metoda get este de tip blocking (pana cand rezultatul devine disponibil)
Cluj-Napoca - 4 Noiembrie 2015
Threaduri daemon
• Un thread daemon furnizeaza un serviciu general programului care ruleaza in background pe durata executiei programului
• Intr-un program, cand toate threadurile non-daemon isi termina executia, programul este terminat, JVM omorand toate threadurile daemon
• Daca exista threaduri non-daemon care se executa, programul nu se termina
• Main este executat intr-o instanta non-daemon • Un thread se marcheaza ca si daemon inainte ca sa se inceapa executia
acestuia cu start • Daca un thread daemon creaza alte threaduri, acestea devin daemon la
randul lor
Crearea unor interfete grafice responsive
• Interfetele grafice trebuie sa raspunda rapid inputului utilizatorului chiar daca acesta presupune calcule sofisticate si de lunga durata
• Pentru a realiza un program care raspunde inputului utilizatorului, taskul de lunga durata trebuie rulat in thread nou (metoda run)
Cluj-Napoca - 4 Noiembrie 2015
Prinderea exceptiilor • Daca apare o exceptie in metoda run, aceasta se va propaga pana la consola, in cazul
in care exceptia nu e rezolvata in run • Problema e rezolvata cu Executors • Exceptiile aruncate de metoda run nu pot fi prinse cu try-catch in jurul comenzii exec
a executorului • Prinderea unei exceptii aruncate de metoda run a unui thread
– Se implementeaza interfata Thread.UncaughtExceptionHandler, creandu-se o clasa handler de exceptie
– Pentru threadul care ruleaza taskul, se asigneaza handlerul de exceptie cu metoda setUncaughtExceptionHandler
– Aceasta operatie poate fi scrisa in medoa newThread a unui ThreadFactory, si apoi se pot utiliza executorii
– Se poate asigna handlerul de exceptii implicit a clasei Thread cu setDefaultUncaughtException
Cluj-Napoca - 4 Noiembrie 2015
Cluj-Napoca - 11 Noiembrie 2015
Concurenta in Java – curs 11 Partajarea resurselor
- Informatică Economică, an III –
Gheorghe Cosmin Silaghi
Partajarea resurselor – mutex
" Douasaumaimultethreaduripotinterfera,colizionandpeaceasiresursa" Problemaaparecandthreadurileconsumatoareseinterferacuceleproducatoarepeaceasi
resursa" Estenevoiedeunmecanismcaresaprevinadouataskurisau4lizezeaceasiresursasensibila
inacelasi4mp" Mecanismmutex(mutualexclusion):seserializeazaaccesultaskurilorlaresursapartajata
Exempludemecanismmutex:" Sepuneunlacatperesursacaretrebuieu4lizatapartajat,primultaskcareareaccesla
resursablocheazaaccesulcelorlaltetaskuri,panacandacestaisiterminaopera4aperesursa
Cluj-Napoca - 11 Noiembrie 2015
Partajarea resurselor - synchornized
• Cuvantul cheie synchornized: realizeaza mutual exclusion pentru o resursa • Resursa partajata se incapsuleaza intr-un obiect • Toate metodele care utilizeaza resursa sunt marcate ca si synchornized • Mecanismul synchronized: fiecare obiect are un monitor (lacat). Cand un
thread intra in zona de cod synchronized, threadul achizitioneaza monitorul, si nici un alt thread nu va mai putea intra intr-o zona synchornized a aceluiasi obiect.
• Daca primul thread care a achizitionat monitorul intra intr-o noua zona synchornized a aceluiasi obiect, se tine un contor a numarului de monitoare achizitionate de thread
• Exista si un monitor la nivel de clasa pt synchronized la metode statice
Cluj-Napoca - 11 Noiembrie 2015
Cluj-Napoca - 11 Noiembrie 2015
Mecanism mutex explicit: Lock
• sectiuni critice : zonele de cod unde poate sa apara coliziunea intre threaduri
• Pentru un obiect de tip Lock: metodele lock() si unlock()
• Imediat dupa lock() trebuie sa fie inserat un block try-finally cu unlock() in finally
• Blocul try trebuie sa contina comanda return
Avantajele mecanismului Lock
• Avantajul Lock asupra synchronized: in metodele synchronized pot aparea exceptii, si atunci nu exista nici o sansa sa se readuca sistemul in stare valida
• Cu Lock, se utilizeaza mecanismul try-finally, si finally se executa in orice situatie (chiar si la o exceptie)
• Sansa pt erori cu synchronized este mai redusa, se vor utiliza Lock doar in cazuri speciale
• Exemplu de situatie speciala: este nevoie de un lock pe o durata specificata de timp
• tryLock(): metoda non-blocking prin care se incearca achizitionarea lock-ului
• tryLock(argumente): metoda care asteapta un anumit timp pt achizitionarea lockului
Cluj-Napoca - 11 Noiembrie 2015
Cluj-Napoca - 11 Noiembrie 2015
Atomicitate si volatilitate
• O operatie este atomica daca ea nu poate fi intrerupta de thread scheduler • Ex de operatii atomice: operatii simple executate pe tipuri primitive altele decat long si
double (pe sisteme 32 biti) • Visibilitate: modificari efectuate de un task chiar daca acestea sunt atomice, pot sa nu
fie vizibile altor taskuri (de ex. Valoarea modificata a variabilei poate fi stocata intr-un registru temporar)
• Mecanismul de sincronizare forteaza ca modificarile unui task sa fie vizibile in toata aplicatia, chiar si pe multiprocesor
• Cuvantul cheie volatile: asigura vizibilitatea: imediat ce un thread scrie o valoare intr-o variabila volatile, acea valoare va fi disponibila pt read
• Este safe sa utilizam volatile in loc de synchronized, doar daca clasa are un singur camp care poate fi modificat
Cluj-Napoca - 11 Noiembrie 2015
Sectiuni critice
• Avem nevoie de sectiuni critice daca partea critica este o bucata de cod dintr-o metoda (spre deosebire de intreaga metoda)
• Sectiunea critica poate sa fie marcata de cuvantul cheie synchronized(obiect) • Monitorul se achizitioneaza pt obiectul specificat • Daca se sincronizeaza doar pe sectiuni critice (si nu pe toata metoda) se poate
castiga timp pretios la executia programului • Pt sectiuni critice se pot folosi si obiecte de tip Lock • La sincronizare pe sectiuni critice, trebuie sa se utilizeze acelasi obiect ca si tinta a
sincronizarii
Stari ale unui thread • New: starea unui thread e new imediat dupa ce aceasta a fost creat. Threadul devine
eligibil să fie alocat către CPU spre executie • Runnable: threadul poate să fie rulat. Schedulerul nu este impiedicat de nimic ca sa
puna threadul in executie • Blocked: taskul poate si fie executat, dar exista ceva ce previne aceasta • Dead: un thread dead sau terminat nu mai poate fi alocat de către scheduler
• A realiza return din metoda run pune threadul in starea dead
Cum se pune un thread in starea blocked: • Metoda sleep • Metoda wait, threadul devine runnable dupa ce primeste un notify sau signal • Threadul asteapta o operatie de I/O sa fie finalizata • Threadul apeleaza o metoda synchornized si se asteapta achizitia monitorului •
Cluj-Napoca - 11 Noiembrie 2015
Intreruperea taskurilor • Iesire din metoda run: verificarea unui flag si return • A intrerupe executia unui task in mijlocul metodei run este similar cu a arunca o
exceptie • Apelul metodei interrupt() a clasei Thread: se seteaza statusul interrupted pentru acel
task • Un thread cu statusul interrupted va arunca o exceptie de tipul InterruptedException
daca acest task este deja blocat sau incearca realizarea unei operatii blocante • Statusul interrupted va fi resetat la momentul aruncarii exceptiei sau cand taskul
apeleaza Thread.interrupted()
Cluj-Napoca - 11 Noiembrie 2015
Intreruperea taskurilor rulate cu executors
• Metoda shutdownNow() a unui executor apeleaza Thread.interrupt() la fiecare thread pornit de executor
• Apelul cancel pe un obiect Future<?> genereaza interrupt • Taskurile blocate de I/O sau synchronized nu se intrerup cu interrupt • Atentie: interrupt() apare la inchiderea (close) unui socket dar nu la close
pe un I/O obisnuit • Taskurile blocate datorita synchornized nu sunt intrerupte cu interrupt • Sectiunile critice gardate de ReentrantLock pot fi intrerupte
Cluj-Napoca - 11 Noiembrie 2015
Cooperare intre taskuri • Problema cooperarii intre taskuri nu se refera la accesul la o resursa partajata • Este vorba de modul in care taskurilor pot lucra in comun pentru atingerea aceluiasi
obiectiv: un task trebuie realizat inaintea altuia • Problema fundamentala la cooperare: Handshaking
• Se rezolva prin extinderea mecanismului excluderii mutuale • Un task are posibilitatea de a-si suspenda executia pana in momentul in care apare
un eveniment exterior lui
• Metodele wait si notifyAll ale clasei Object
Cluj-Napoca - 11 Noiembrie 2015
Cooperarea intre taskuri (II)
• Wait() permite sa se astepte realizarea unor conditii care sunt in afara controlului taskului curent
• Wait() suspenda taskul pana cand apare un notify sau un notifyAll • Wait e diferit de sleep si yield - acestea nu elibereaza lock-ul obiectului • Wait() suspenda executia threadului si elibereaza lock-ul obiectului • wait() poate avea ca si argument un numar de milisecunde • Wait(), notify() si notifyAll() sunt metode ale Object, ele pot fi apelate doar din
metode synchornized (ele elibereaza lock-ul) • Wait() apelat dintr-o metoda ne-synchronized genereaza IllegalMonitorStateException • Wait este inglobat intr-un while:
– Mai multe taskuri pot sa astepte dupa acelasi lock pentru acelasi motiv – Pana ca taskul sa ajunga la wait() e posibil ca alt task sa schimbe situatia si taskul sa
trebuiasca resuspendat prin wait() – Este posibil ca taskuri diferite sa ceara acelasi lock pentru motive diferite
Cluj-Napoca - 11 Noiembrie 2015
Semnale pierdute Poate aparea semnal notify pierdut T1: synchronized(sharedMonitor) { <setup condition for T2> sharedMonitor.notify(); } T2: while(someCondition) { // Point 1 synchronized(sharedMonitor) { sharedMonitor.wait(); } }
Cluj-Napoca - 11 Noiembrie 2015
Corect: T1: synchronized(sharedMonitor) { <setup condition for T2> sharedMonitor.notify(); } T2: synchronized(sharedMonitor) { while(someCondition) { sharedMonitor.wait(); } }
Deadlock • Apare atunci cand taskurile asteapta utilizarea unei resurse unul dupa
celalalt • Problema filosofilor (Dijkstra):
– Filosofii desfasoara urmatoarele activitati: mananca si gandesc – Pentru a manca, ei pot utiliza un numar egal de furculite, ex. 5 filosofi
utilizeaza exact 5 furculite – Pentru a putea manca, fiecare filosof trebuie sa achizitioneze 2 furculite,
apoi executa operatia “a manca”, apoi elibereaza furculitele utilizate
Cluj-Napoca - 11 Noiembrie 2015
Deadlock (II) • Apare atunci cand urmatoarele 4 conditii sunt simultan indeplinite:
– Excluderea mutuala: cel putin una din resursele folosite de catre taskuri nu pot fi utilizate in comun
– Cel putin un task detine o astfel de resursa si asteapta sa achitioneze o alta asemenea resursa detinuta de alt task
– O astfel de resursa nu poate fi luata in mod fortat de la un task – Poate aparea un wait circular
• Rezolvarea situatiei de deadlock: – Impiedicarea realizarii uneia din cele 4 conditii de mai sus
Cluj-Napoca - 11 Noiembrie 2015