Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

1 Fejlett Programozási Technikák 2. 15/4. Fejlett Programozási Technológiák 2. 2 Az előző előadás tartalma Java Virtual Machine  Memória kezelés  Szemét.

Hasonló előadás


Az előadások a következő témára: "1 Fejlett Programozási Technikák 2. 15/4. Fejlett Programozási Technológiák 2. 2 Az előző előadás tartalma Java Virtual Machine  Memória kezelés  Szemét."— Előadás másolata:

1 1 Fejlett Programozási Technikák 2. 15/4

2 Fejlett Programozási Technológiák 2. 2 Az előző előadás tartalma Java Virtual Machine  Memória kezelés  Szemét gyűjtő  Hiba keresés támogatás  Fordító Java nyelv alapjai  Változók  Operátorok, Vezérlő szerkezetek  Osztályok  Interfészek  RTTI  Reflexió  Alap objektumok  Csomagok JAR fájlok

3 Fejlett Programozási Technológiák 2. 3 Források New Features and Enhancements J2SE 5.0 (http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html )http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html Thinking in Java, 3rd Edition (http://mindview.net/Books/TIJ/DownloadSites)http://mindview.net/Books/TIJ/DownloadSites  Error Handling with Exceptions  Concurrency

4 Fejlett Programozási Technológiák 2. 4 A mai előadás tartalma: Újdonságok az 1.5-ös Java-ban  Generics  Metaadatok  Új ciklus  Enum kezelés  Statikus import Hibakezelés  Egyszerű kivételek  Kivétel elfogása  Saját kivételek gyártása  Bármely kivétel elfogása  Finally Többszálúság  Motiváció  Szálkezelés alapjai  Megosztott erőforrások kezelése  Szál állapotok  Együttműködés szálak között

5 Fejlett Programozási Technológiák 2. 5 Újdonságok az 1.5-ös Java-ban Generics  Fordítás időben történő típus ellenőrzés a kollekciókhoz (többek között) Metaadatok  Olyan megjegyzések kódba melyek a class fájlba is bekerülnek így fejlesztő, kód generáló eszközök segítségével is olvashatóak Új ciklus  Mellőzhetjük az index változókat Enum kezelés  Típus biztos felsorolt típusok használata Statikus import  Importálás után a statikus változókra az osztályok neve nélkül is hivatkozhatunk

6 Fejlett Programozási Technológiák 2. 6 Generics Minden bővítés (downcasting) hibalehetőségeket visz a programba Ezek futás időben derülnek ki! Generics:  Extra típus információ  Absztrakció a típusok felett  Osztályok, Interfészek, Metódusok lehetnek paraméterezettek típusokkal Megvalósítási módok:  Kód specializáció (C++ template)  Kód megosztás (Java) Leggyakoribb használata: List myIntList = new LinkedList(); // 1 myIntList.add(new Integer(0)); // 2 Integer x = (Integer) myIntList.iterator().next(); // 3 List myIntList = new LinkedList (); // 1’ myIntList.add(new Integer(0)); //2’ Integer x = myIntList.iterator().next(); // 3’

7 Fejlett Programozási Technológiák 2. 7 Generics és altípusok Példa:  List ls = new ArrayList (); //1  List lo = ls; //2  lo.add(new Object()); // 3  String s = ls.get(0); // 4 Joker karakter: List Felülről korlátos: List Alulról korlátos: List Paraméteres metódus: static void fromArrayToCollection(T[] a, Collection c) { for (T o : a) { c.add(o); // correct }}

8 Fejlett Programozási Technológiák 2. 8 Metaadatok Gyakran szükség van a kód mellet egyéb információra is pl.: interfész leirásra, EJB telepítés leíró, …  Ez akár automatikusan is legyártható, ha a kódban megtudjuk jelölni a szükséges részeket Eddig is voltak ad-hoc megoldások:  transient Elemei:  Nyelvtan  Feldolgozó API  Class file reprezentáció A javadoc elemeket egészítik ki Új módositó elemként használható a többi módosító elem előtt (public,…) Saját elemeket is tudunk definiálni Ha nincs adattagja akkor használatánál elhagyhatjuk a public class TimeTravel {... }

9 Fejlett Programozási Technológiák 2. 9 Példa RequestForEnhancement { int id(); String synopsis(); String engineer() default "[unassigned]"; String date(); default "[unimplemented]"; id = , synopsis = "Enable time-travel", engineer = "Mr. Peabody", date = "4/1/3007" ) public static void travelThroughTime(Date destination) {... }

10 Fejlett Programozási Technológiák Új ciklus A kollekciókon történő iterálás eddig: for (Iterator i = c.iterator(); i.hasNext(); ) i.next().cancel(); Az új ciklussal: for (TimerTask t : c) t.cancel();

11 Fejlett Programozási Technológiák Enum kezelés Hasonlít a C++, C# enum kezelésre de osztályként van kezelve azaz:  Metódusokat, mezőket adhatunk hozzá  Az Object metódusait magas szinten implementálja

12 Fejlett Programozási Technológiák Statikus import A statikus változókhoz szükség volt az osztály nevére is:  double r = Math.cos(Math.PI * theta); Az új nyelvtan megengedi:  import static java.lang.Math.*;  double r = cos(PI * theta); Akkor alkalmazzuk, ha viszonylag kevés változót szeretnénk így használni, sok változó esetén olvashatatlan lesz a kód

13 Fejlett Programozási Technológiák Hibakezelés Java: ”A rosszul megírt program nem fog futni” Legjobb a hibákat még futás előtt kiszűrni Nem tudunk minden hibát fordításkor kiszűrni (felhasználó, hálózat, …) A hibák nagy részét futás közben kell lekezelni úgy, hogy lehetőségünk legyen átadni a hibakezelőnek a hiba forrását is C-ben és néhány régebbi nyelvben több hibakezelési mód is elterjedt. Ezek általában flag-eket használtak a hibák jelzésére (flaggink). Probléma:  Programozók: ”Hibák lehetnek de nem az én kódomban”  A hibák figyelése minden egyes függvényhíváskor átláthatatlanná teszi a kódot  Ilyen módon nehéz volt nagy robosztus karbantartható kódokat gyártani  Nagyszámú változó (hibaállapot)  Hasonló problémákat kell kezelni a programban több helyen is (cut&paste)

14 Fejlett Programozási Technológiák Megoldások Basic:  on error goto C++:  Az Ada nyelv hibakezelésén alapul Java:  A C++ hibakezelésén alapul

15 Fejlett Programozási Technológiák Exception - Kivétel Kivétel: Olyan probléma amely megakadályozza a metódus további futását az adott környezetben. (Nem egyszerű hiba mely bekövetkezésekor az adott környezetben elegendő információnk van a normál folytatáshoz) Kivétel: Ahol a probléma jelentkezik nem feltétlenül tudjuk mit kell tennünk vele. Kivételt teszünk vele és máshol egy magasabb szinten kezeljük le. (0- val osztás) Kivétel kezelés:  befejezés  folytatás Hiba esetén a következőket illik megtenni:  Értesíteni a felhasználót  Elmenteni minden munkát  Lehetővé tenni a felhasználónak a programból való kilépést

16 Fejlett Programozási Technológiák Típusok Throwable:  Error (fordításkori és rendszer hibák)  Exception  RunTimeException

17 Fejlett Programozási Technológiák Egyszerű kivételek Amikor kivételt dobunk:  Kivétel objektumot hozunk létre a heap memória területen a new operátorral  A végrehajtás jelenlegi útvonala megszakad  A kivétel objektum referenciája kikerül a jelenlegi futási környezetből  A kivétel kezelő mechanizmus keresi a megfelelő helyet a folytatásra if(t == null) throw new NullPointerException();

18 Fejlett Programozási Technológiák Kivétel argumentum Két konstruktorunk van:  default  string argumentummal rendelkező throw new NullPointerException("t = null"); Throwable ős osztály

19 Fejlett Programozási Technológiák Try catch blokk A kivételt kezelnünk kell A kód és a hibakezelés elkülönülhet Olyan nyelvekben ahol nincs kivétel kezelés minden egyes metódus hívást ilyen blokkba kellene tenni! try – catch - finally blokk try { // Code that might generate exceptions } catch(Type1 id1) { // Handle exceptions of Type1 } catch(Type2 id2) { // Handle exceptions of Type2 } catch(Type3 id3) { // Handle exceptions of Type3 }

20 Fejlett Programozási Technológiák Saját kivételek A JDK-ban ugyan sok kivétel van de nem tudhatják milyen igényeink lehetnek Egy meglévő kivétel osztályból kell származtatnunk Gyakran nincs konstruktor:  ez esetben a fordító gyárt egyet  nem tudjuk a string argumentumot használni  leggyakrabban a kivétel neve elég információ (egyszerűség kívánatos, mások használhatják)

21 Fejlett Programozási Technológiák Példa class SimpleException extends Exception {} public class SimpleExceptionDemo { public void f() throws SimpleException { System.out.println("Throw SimpleException from f()"); throw new SimpleException(); } public static void main(String[] args) { SimpleExceptionDemo sed = new SimpleExceptionDemo(); try { sed.f(); } catch(SimpleException e) { System.err.println("Caught it!"); } }); } } ///:~

22 Fejlett Programozási Technológiák class MyException extends Exception { public MyException() {} public MyException(String msg) { super(msg); } } public class FullConstructors { public static void f() throws MyException { System.out.println("Throwing MyException from f()"); throw new MyException(); } public static void g() throws MyException { System.out.println("Throwing MyException from g()"); throw new MyException("Originated in g()"); } public static void main(String[] args) { try { f(); } catch(MyException e) { e.printStackTrace(); } try { g(); } catch(MyException e) { e.printStackTrace(); } }); } } ///:~ Throwing MyException from f() MyException FullConstructors.f (.*) FullConstructors.main(.*) Throwing MyException from g() MyException: Originated in g() FullConstructors.g(.*) FullConstructors.main(.*)

23 Fejlett Programozási Technológiák Saját kivétel class MyException2 extends Exception { private int x; public MyException2() {} public MyException2(String msg) { super(msg); } public MyException2(String msg, int x) { super(msg); this.x = x; } public int val() { return x; } public String getMessage() { return "Detail Message: "+ x + " "+ super.getMessage(); }

24 Fejlett Programozási Technológiák Kivétel specifikálás (checked exceptions ) Java-ban kötelező megadnunk egy-egy metódusoknál a nem kezelt kivételek listáját (többet igen de kevesebbet nem mondhatunk, RunTime kivétel) Jó ha tudják a metódusunkat használó programozók mire számíthatnak (általában nem férnek hozzá a forráshoz) void f() throws TooBig, TooSmall, DivZero {

25 Fejlett Programozási Technológiák Bármely kivétel kezelése Tudunk olyan kezelőt írni amely bármely kivételt képes kezelni: Ekkor a Throwable osztály megfelelő metódusai segítségével tudunk egyéb információt megtudni  String getMessage( )  String getLocalizedMessage( )  String toString( )  void printStackTrace( )  void printStackTrace(PrintStream)  void printStackTrace(java.io.PrintWriter) catch(Exception e) { System.err.println("Caught an exception"); }

26 Fejlett Programozási Technológiák Példa public class ExceptionMethods { public static void main(String[] args) { try { throw new Exception("My Exception"); } catch(Exception e) { System.err.println("Caught Exception"); System.err.println("getMessage():" + e.getMessage()); System.err.println("getLocalizedMessage():" + e.getLocalizedMessage()); System.err.println("toString():" + e); System.err.println("printStackTrace():"); e.printStackTrace(); } } ///:~ Caught Exception getMessage():My Exception getLocalizedMessage():My Exception toString():java.lang.Exception: My Exception printStackTrace(): java.lang.Exception: My Exception ExceptionMethods.main(.*)

27 Fejlett Programozási Technológiák A kivétel továbbdobása Előfordul, hogy adott helyen nem akarjuk kezelni, hanem továbbadjuk egy magasabb szintnek (Exception) Nem veszi figyelembe az ugyanazon szinten lévő catch blokkokat Ez esetben ugyanaz a kivétel objektum kerül továbbításra (stack trace) Amennyiben az új környezetet akarjuk átadni akkor: fillInStackTrace( ) metódust kell használnunk catch(Exception e) { System.err.println("An exception was thrown"); throw e; }

28 Fejlett Programozási Technológiák public class Rethrowing { public static void f() throws Exception { System.out.println("originating the exception in f()"); throw new Exception("thrown from f()"); } public static void g() throws Throwable { try { f(); } catch(Exception e) { System.err.println("Inside g(),e.printStackTrace()"); e.printStackTrace(); throw e; // 17 // throw e.fillInStackTrace(); // 18 } public static void main(String[] args) throws Throwable { try { g(); } catch(Exception e) { System.err.println( "Caught in main, e.printStackTrace()"); e.printStackTrace(); } } ///:~ originating the exception in f() Inside g(),e.printStackTrace() java.lang.Exception: thrown from f() at Rethrowing.f(Rethrowing.java:9) at Rethrowing.g(Rethrowing.java:12) at Rethrowing.main(Rethrowing.java:23) Caught in main, e.printStackTrace() java.lang.Exception: thrown from f() at Rethrowing.f(Rethrowing.java:9) at Rethrowing.g(Rethrowing.java:12) at Rethrowing.main(Rethrowing.java:23) originating the exception in f() Inside g(),e.printStackTrace() java.lang.Exception: thrown from f() at Rethrowing.f(Rethrowing.java:9) at Rethrowing.g(Rethrowing.java:12) at Rethrowing.main(Rethrowing.java:23) Caught in main, e.printStackTrace() java.lang.Exception: thrown from f() at Rethrowing.g(Rethrowing.java:18) at Rethrowing.main(Rethrowing.java:23)

29 Fejlett Programozási Technológiák Kivétel láncolás Gyakran egy kivétel kezelése után létrehozunk egy új kivételt és szeretnénk megőrizni a régi kivételt is A JDK 1.4-től lehetőségünk van erre a Throwable objektum és alobjektumainak konstruktora objektum fogadására is képes (sok esetben csak initCause( ) )

30 Fejlett Programozási Technológiák Példa public Object setField(String id, Object value) throws DynamicFieldsException { if(value == null) { DynamicFieldsException dfe = new DynamicFieldsException(); dfe.initCause(new NullPointerException()); throw dfe; }

31 Fejlett Programozási Technológiák RunTimeException if(t == null) throw new NullPointerException(); Kellemetlen lenne minden egyes referncia átadásnál figyelni, hogy null értékkű-e Nem kell ezzel foglalkoznunk mivel a java automatikusan meghívja Az ehhez hasonló kivételeket a RunTimeException osztályba fogja össze Ezeket nem szükséges a metódus fejlécében jeleznünk Amennyiben ezen hibák jelentkeznek akkor:  Olyan hiba merül fel amit nem tudunk kezelni (null)  Olyan hiba amelyre programozóként figyelnünk kellett volna (tömb index) Segítenek a hibakeresésben

32 Fejlett Programozási Technológiák Példa public class NeverCaught { static void f() { throw new RuntimeException("From f()"); } static void g() { f(); } public static void main(String[] args) { g(); } } ///:~ Exception in thread "main" java.lang.RuntimeException: From f() at NeverCaught.f(NeverCaught.java:7) at NeverCaught.g(NeverCaught.java:10) at NeverCaught.main(NeverCaught.java:13)

33 Fejlett Programozási Technológiák Finally Mivel a program végrehajtása nem kerül vissza oda ahol a kivétel keletkezett, szeretnénk bizonyos dolgokat mindenképpen végrehajtani A szemétgyűjtő ugyan felszabadítja a memóriát előbb vagy utóbb azonban a finally determinisztikus Probléma: kivétel elveszése!

34 Fejlett Programozási Technológiák Példa class ThreeException extends Exception {} public class FinallyWorks { static int count = 0; public static void main(String[] args) { while(true) { try { if(count++ == 0) throw new ThreeException(); System.out.println("No exception"); } catch(ThreeException e) { System.err.println("ThreeException"); } finally { System.err.println("In finally clause"); if(count == 2) break; // out of "while" } } ///:~ ThreeException In finally clause No exception In finally clause

35 Fejlett Programozási Technológiák Kivétel megszorítások Ha egy metódust felülírunk akkor csak olyan kivételeket dobhatuk melyek az ős metóduban fejlécében is definiálva voltak A dobott kivételek száma nem gyarapodhat A konstruktorkra ez nem vonatkozik

36 Fejlett Programozási Technológiák Probléma class VeryImportantException extends Exception { public String toString() { return "A very important exception!"; } class HoHumException extends Exception { public String toString() { return "A trivial exception"; } public class LostMessage { void f() throws VeryImportantException { throw new VeryImportantException(); } void dispose() throws HoHumException { throw new HoHumException(); } public static void main(String[] args) throws Exception { LostMessage lm = new LostMessage(); try { lm.f(); } finally { lm.dispose(); } } ///:~ Exception in thread "main" A trivial exception", LostMessage.dispose(LostMessage.java:24) LostMessage.main(LostMessage.java:31)

37 Fejlett Programozási Technológiák Szálak - Motiváció Válaszképes felhasználói interfész  egyszerre kell több dolgot is csinálni  ha ki szeretnénk lépni akkor bárhonnan kiléphessen  tudjunk valamit csinálni amíg az I/O műveletek folynak  több processzoros gépnél kihasználja a processzorokat  virtuális CPU

38 Fejlett Programozási Technológiák Szál (thread) Egyszerű szekvenciális parancssor a programon belül. Könnyűsúlyú folyamat:  megosztva használja a kód és az adat szekciót  csökken a ”context-switch” végrehajtási idő Segítségével egyszerre több feladatot végezhetünk:  képernyő frissítés  hálózat kezelés …

39 Fejlett Programozási Technológiák Thread osztály a Thread egy virtuális processzort valósít meg  kódot futtat  adat területet használ Létrehozása: két módon tudunk szálat megvalósító osztályt definiálni:  a Thread osztályból származtatva és felülírva a run metódust  megvalósítva a Runnable interfészt

40 Fejlett Programozási Technológiák A run metódus felülírása 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 { sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("DONE! " + getName()); } }

41 Fejlett Programozási Technológiák Futtatás public class TwoThreadsDemo { public static void main (String[] args) { new SimpleThread("Jamaica").start(); new SimpleThread("Fiji").start(); } 0 Jamaica 0 Fiji 1 Jamaica 1 Fiji 2 Fiji 2 Jamaica 3 Fiji 3 Jamaica 4 Jamaica 4 Fiji 5 Fiji 6 Fiji 7 Fiji 5 Jamaica 8 Fiji 6 Jamaica 9 Fiji 7 Jamaica DONE! Fiji 8 Jamaica 9 Jamaica DONE! Jamaica

42 Fejlett Programozási Technológiák A Runnable interfész megvalósítása public class SimpleThread implements Runnable { Thread SimpleThread; public SimpleThread(String str) { SimpleThread = new Thread(this, str);} public void start() {SimpleThread.start(); } public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + myThread.getName()); try { myThread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("DONE! " + myThread.getName()); }

43 Fejlett Programozási Technológiák Mikor melyik módot válasszuk ? Amennyiben osztályunknak származnia kell valahonnan akkor az interfész a megoldás (pl Applet esetén) Egyébként tetszőleges

44 Fejlett Programozási Technológiák A szál életciklusa új futtatható blokkolt halott sleep start suspend wait notify resume done sleeping run metódus kilép stop

45 Fejlett Programozási Technológiák Állapotok I. új szál  amikor a new operátorral létrehozzuk még nem fut  ekkor a new állapotban van runnable  a megfelelő erőforrások lefoglalását, a szál adminisztrálását, a szál futását a start metódus segítségével tudjuk elindítani a new állapotból.  ebben az állapotban a szál nem feltétlenül fog futni. Az operációs rendszer feladata a megfelelő futási idő biztosítása számára.  a szálak közötti váltás operációs rendszer függő (pl.: solaris esetén green threads, windows esetén mindegyik szálnak egy időszelet)

46 Fejlett Programozási Technológiák blokkolt szálak a következő módokon kerülhetnek ebbe az állapotba:  a sleep() metódus eredményeként (ekkor adott ideig lesz itt, try használata kötelező)  yield() segítségével az azonos prioritásúak futhatnak egyébként nem számít  join() egy adott ideig, vagy az adott szál futásának végéig  egy olyan művelet végrehajtása esetén mely input/output műveletekkel blokkolt és addig nem tér vissza míg ezek be nem fejeződtek  a wait() metódus meghívására (másik szálnak meg kell hívnia a notify vagy notifyAll metódust)  amikor olyan objektumhoz próbál hozzáférni amely zárolt  a suspend() metódus meghívására (ez már elavult) a resmue() metódussal lehet visszahozni. futtatható állapotba csak úgy kerülhetnek vissza ha a blokkolást előidéző eseménynek megfelelő esemény következik be Állapotok II.

47 Fejlett Programozási Technológiák Állapotok III. halott szálak  a run metódus kilép  hirtelen meghal mert egy kezeletlen kivétel miatt megszűnik a run metódus  a stop metódus elavult ezért ne használjuk  az isAlive metódus segítségével nézhetjük meg, hogy él-e még.

48 Fejlett Programozási Technológiák A run metódus kezelése I. a feladat befejezése után kilép: public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getName()); try { sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("DONE! " + getName()); } }

49 Fejlett Programozási Technológiák Figyeli, hogy ki kell-e lépnie: public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e){} } public void stop() { clockThread = null; } A run metódus kezelése II.

50 Fejlett Programozási Technológiák Prioritás a szálak versenyeznek a CPU használatáért nagyobb prioritású szálak előnyben vannak a kisebb prioritású szálakkal szemben a kisebb prioritású szálak csak akkor jutnak CPU időhöz, ha a nagyobb prioritású szálak már nem tartanak igényt a CPU-ra az egyenlő prioritású szálak kezelése operációs rendszer függő  win9x, WinNT… az egyenlő prioritású szálak felváltva kapnak CPU időt (időosztás)  solaris az egyenlő prioritású szálak csak között csak a feladat befejezése után történik váltás (probléma az önző szálak kezelése) a setPriority() metódussal lehet beállítani egy szál prioritását (MAX_PRIOROTY=10, MIN_PRIORITY=1)

51 Fejlett Programozási Technológiák Példa: public class SimpleThread implements Runnable { Thread SimpleThread; public SimpleThread(String str) { SimpleThread = new Thread(this, str); } public void start() { SimpleThread.start(); } public void setPriority(int i) { SimpleThread.setPriority(i); } public void run() { Thread myThread = Thread.currentThread(); for (int i = 0; i < 10; i++) { for (int c = 0; c < ; c++); System.out.println(i + " " + SimpleThread.getName()); } System.out.println("DONE! " + SimpleThread.getName()); }

52 Fejlett Programozási Technológiák Egyforma prioritás public class ThreeThreadsTest { public static void main (String[] args) { SimpleThread t; SimpleThread t1; t = new SimpleThread("Jamaica"); t.setPriority(1); t1 = new SimpleThread("Kolumbia"); t1.setPriority(1); t1.start(); t.start(); } 0 Kolumbia 1 Kolumbia 2 Kolumbia 0 Jamaica 1 Jamaica 2 Jamaica 3 Jamaica 4 Jamaica 3 Kolumbia 4 Kolumbia 5 Kolumbia 6 Kolumbia 5 Jamaica 6 Jamaica 7 Jamaica 8 Jamaica 9 Jamaica 7 Kolumbia 8 Kolumbia 9 Kolumbia DONE! Kolumbia DONE! Jamaica

53 Fejlett Programozási Technológiák Különböző prioritás public class ThreeThreadsTest { public static void main (String[] args) { SimpleThread t; SimpleThread t1; t = new SimpleThread("Jamaica"); t.setPriority(10); t1 = new SimpleThread("Kolumbia"); t1.setPriority(1); t1.start(); t.start(); } 0 Jamaica 1 Jamaica 2 Jamaica 3 Jamaica 4 Jamaica 5 Jamaica 6 Jamaica 7 Jamaica 8 Jamaica 9 Jamaica DONE! Jamaica 0 Kolumbia 1 Kolumbia 2 Kolumbia 3 Kolumbia 4 Kolumbia 5 Kolumbia 6 Kolumbia 7 Kolumbia 8 Kolumbia 9 Kolumbia DONE! Kolumbia

54 Fejlett Programozási Technológiák Megjegyzés olyan szálakat kell írnunk melyek nem önzőek az operációs rendszerek különbözőek, ha platform független programot akarunk írni akkor nekünk kell gondoskodnunk a megfelelő időosztásról a yield() metódus segítségével tudjuk egy szál futását felfüggeszteni és a CPU-t átadni egy legalább ilyen prioritású szálnak (solaris) nem minden operációs rendszer rendelkezik 10 prioritási szinttel (pl winnt 7) a szálak prioritásukat a létrehozó száltól öröklik

55 Fejlett Programozási Technológiák Daemon thread Háttérben fut Amikor minden szál véget ér akkor ő is befejezi tevékenységét setDaemon() isDaemon()

56 Fejlett Programozási Technológiák Erőforrás megosztás Egyes feladatokat nem lehet megoldani egymástól független szálakkal (pl.: közös erőforrás használata módosítása) Hibás működéshez vezethet amennyiben nem gondoskodunk zárolásról a közös erőforrás használatakor pl.: két vagy több szál bankbetétek között végez tranzakciókat. A művelet bármikor megszakadhat (windows) és nem konzekvens állapot maradhat, amit egy másik szál felhasználhat. a problémát az adatmódosító metódus megszakíthatósága okozza

57 Fejlett Programozási Technológiák Példa public class AlwaysEven { private int i; public void next() { i++; i++; } public int getValue() { return i; } public static void main(String[] args) { final AlwaysEven ae = new AlwaysEven(); new Thread("Watcher") { public void run() { while(true) { int val = ae.getValue(); if(val % 2 != 0) { System.out.println(val); System.exit(0); } } } }.start(); while(true) ae.next(); } } ///:~

58 Fejlett Programozási Technológiák Zárolás synchronized{} atomi műveleteket nem kell szinkronizálni  long, double esetén volatile a zárolt objektumhoz csak egy szál férhet hozzá ha egy szál használ egy zárolt objektumot és meghív egy másik szálat akkor a másik szál hozzáférhet az objektumhoz minden objektumnak van egy zárolás számlálója egy szál egyszerre több objektumot is zárolhat a szál ütemező periodikusan aktiválja a szálakat, azok melyek egy zárolt objektumra várakoznak a következő soron kívüli futási jogot kapnak. metódus zárolás synchronized x() kód blokk zárolás synchronized(objektum){} – gyorsabb működés

59 Fejlett Programozási Technológiák Példa public class SynchronizedEvenGenerator implements Invariant { private int i; public synchronized void next() { i++; i++; } public synchronized int getValue() { return i; } public InvariantState invariant() { int val = getValue(); if(val % 2 == 0) return new InvariantOK(); else return new InvariantFailure(new Integer(val)); } public static void main(String[] args) { SynchronizedEvenGenerator gen = new SynchronizedEvenGenerator(); new InvariantWatcher(gen, 4000); // 4-second timeout while(true) gen.next(); } } ///:~

60 Fejlett Programozási Technológiák wait, notify, notifyAll előfordulhat olyan eset amikor egy szál a másik akciójára vár ilyenkor mivel a közös objektumot zárolt függvényeken keresztül lehet elérni ez végtelen ciklushoz vezetne wait – ha egy szál meghívja a wait() metódust akkor az objektum felszabadul és a szál blokkolva lesz amíg az adott objektumnál egy másik szál meg nem a hívja a notify, notifyAll metódust érdemes a notifyAll metódust használni mivel a másik a blokkolt szálak közül csak egyet szabadít fel azt is véltelenszerűen

61 Fejlett Programozási Technológiák Példa: Tároló objektum: Tarolo Adat forrás: Producer Adat nyelő: Consumer main: PTest

62 Fejlett Programozási Technológiák Tarolo.java public class Tarolo { private int contents; private boolean available = false; public synchronized int get() { while (available == false) { try { wait(); } catch (InterruptedException e) { } } System.out.println("Olvasgatok"); available = false; notifyAll(); return contents; } public synchronized void put(int value) { while (available == true) { try { wait(); } catch (InterruptedException e) { } } System.out.println("Irogatok"); contents = value; available = true; notifyAll(); }

63 Fejlett Programozási Technológiák public class Producer extends Thread { private Tarolo tarolo; private int number; public Producer(Tarolo c, int number) { tarolo = c; this.number = number; } public void run() { for (int i = 0; i < 10; i++) { tarolo.put(i); System.out.println("Producer #" + this.number + " beirtam: " + i); try { sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { } }

64 Fejlett Programozási Technológiák public class Consumer extends Thread { private Tarolo tarolo; private int number; public Consumer(Tarolo c, int number) { tarolo = c; this.number = number; } public void run() { int value = 0; for (int i = 0; i < 10; i++) { value = tarolo.get(); System.out.println("Consumer #" + this.number + " kiolvastam: " + value); }

65 Fejlett Programozási Technológiák public class PTest { public static void main(String[] args) { Tarolo c = new Tarolo(); Producer p1 = new Producer(c, 1); Consumer c1 = new Consumer(c, 1); c1.start(); p1.start(); } Main

66 Fejlett Programozási Technológiák Eredmény H:\>java PTest Irogatok Olvasgatok Consumer #1 kiolvastam: 0 Producer #1 beirtam: 0 …. Irogatok Olvasgatok Producer #1 beirtam: 8 Consumer #1 kiolvastam: 8 Irogatok Producer #1 beirtam: 9 Olvasgatok Consumer #1 kiolvastam: 9

67 Fejlett Programozási Technológiák Újrafoglalás public class Reentrant { public synchronized void a() { b(); System.out.println("here I am, in a()"); } public synchronized void b() { System.out.println("here I am, in b()"); }

68 Fejlett Programozási Technológiák Szál csoportok a szálakat csoportokba tudjuk foglalni a csoportokon egyszerre tudunk műveleteket végrehajtani egy szál a létrehozásakor helyezhető egy csoportba, ezután már nem mozdítható el ha nem adunk meg mást akkor automatikusan a szülő szál csoportjába kerül új csoportokat létrehozása esetén az új csoport a szülő csoport gyerek csoportja lesz

69 Fejlett Programozási Technológiák A mai előadás tartalma: Újdonságok az 1.5-ös Java-ban  Generics  Metaadatok  Új ciklus  Enum kezelés  Statikus import Hibakezelés  Egyszerű kivételek  Kivétel elfogása  Saját kivételek gyártása  Bármely kivétel elfogása  Finally Többszálúság  Motiváció  Szálkezelés alapjai  Megosztott erőforrások kezelése  Szál állapotok  Együttműködés szálak között

70 Fejlett Programozási Technológiák A következő előadás tartalma ANT JUnit CVS Log4J


Letölteni ppt "1 Fejlett Programozási Technikák 2. 15/4. Fejlett Programozási Technológiák 2. 2 Az előző előadás tartalma Java Virtual Machine  Memória kezelés  Szemét."

Hasonló előadás


Google Hirdetések