Fejlett Programozási Technikák 2.

Slides:



Advertisements
Hasonló előadás
C# nyelvi áttekintő A „Programozás C# nyelven (Illés Zoltán)”
Advertisements

4. alkalom – Hálózat Kezelés
Osztály leszármaztatás

C++ programozási nyelv Gyakorlat hét
Programozás III KOLLEKCIÓK 2..
Adatbányászati technikák (VISZM185)
Öröklődés 2..
© Kozsik Tamás Tömbök, kollekciók és egyéb alaposztályok.
© Kozsik Tamás Beágyazott osztályok A blokkstrukturáltság támogatása –Eddig: egymásba ágyazható blokk utasítások Osztálydefiníciók is egymásba.
© Kozsik Tamás Párhuzamosság A program egyszerre több mindent is csinálhat Lehetőségek: –Számítással egyidőben IO –Több processzor: számítások.
A tételek eljuttatása az iskolákba
Bevezetés a Java programozásba
Fájlkezelés, IO Kivételkezelés Belső osztályok
Abstract osztályok és interface-ek Beolvasás és kiíratás 7. gyakorlat.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 9. Gyakorlat Alap file műveletek.
Programozás II. 3. Gyakorlat C++ alapok.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 6. Gyakorlat const, static, dinamikus 2D.
Követelmények Bevezetés a Javába Első java program írása Dokumentációk
Fejlett Programozási Technológiák II. Világos Zsolt 12. gyakorlat.
Tömbök ismétlés Osztályok Java-ban Garbage collection
VÁLOGATÁS ISKOLÁNK ÉLETÉBŐL KÉPEKBEN.
1. IS2PRI2 02/96 B.Könyv SIKER A KÖNYVELÉSHEZ. 2. IS2PRI2 02/96 Mi a B.Könyv KönyvelésMérlegEredményAdóAnalitikaForintDevizaKönyvelésMérlegEredményAdóAnalitikaForintDeviza.
A Java programozási nyelvSoós Sándor 1/17 Java programozási nyelv 4. rész – Osztályok II. Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai.
A C++ programozási nyelvSoós Sándor 1/15 C++ programozási nyelv Gyakorlat hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
Java programozási nyelv 5. rész – Osztályok III.
C# tagfüggvények.
C# tagfüggvények.
Annotációk a Java 5 nyelvben Kozsik Tamás. Annotációk Módosítószavak bővítése A programszöveg elemeihez rendelhetők –Csomagokhoz, típusokhoz, metódusokhoz,
© Kozsik Tamás Kivételek A program végrehajtása során ritkán bekövetkező események Nem a „fő végrehajtási ág”; logikailag alacsonyabbrendű feladat.
Kivételkezelés.
DRAGON BALL GT dbzgtlink féle változat! Illesztett, ráégetett, sárga felirattal! Japan és Angol Navigáláshoz használd a bal oldali léptető elemeket ! Verzio.
PHP I. Alapok. Mi a PHP? PHP Hypertext Preprocessor Szkriptnyelv –Egyszerű, gyors fejlesztés –Nincs fordítás (csak értelmező) Alkalmazási lehetőségek:
P ROGRAMOZÁS C# - BAN Kivételkezelés. P ÉLDA I. Nullával való osztás miatt kapjuk a hibaüzenetet.
szakmérnök hallgatók számára
Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
1 Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Hernyák Zoltán Programozási Nyelvek II.
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
Javascript Microsoft által készített kiegészítése Statikus típusosság Nagy projektek Windows 8 fejlesztésénél WinRT egy részét ebben írták Nyílt forráskódú,
A klinikai transzfúziós tevékenység Ápolás szakmai ellenőrzése
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 1. gyakorlat.
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 7. gyakorlat.
Komoróczy Tamás 1 Java programozási nyelv A nyelv alapjai.
Java programozási nyelv Adatbekérés konzolról
Generics Krizsán Zoltán. Bemutató A.NET 2.0 verziótól. A.NET 2.0 verziótól. Típusparaméter Típusparaméter Más nyelvben ez a template (sablon). Más nyelvben.
Objektum orientált programozás
1. Melyik jármű haladhat tovább elsőként az ábrán látható forgalmi helyzetben? a) A "V" jelű villamos. b) Az "M" jelű munkagép. c) Az "R" jelű rendőrségi.
Programozás III KIVÉTEL.
> aspnet_regiis -i 8 9 TIPP: Az „Alap” telepítés gyors, nem kérdez, de később korlátozhat.
Programozás III KIVÉTEL. KIVÉTELKEZELÉS Hibátlan program nincs!!! eddig hiba esetén leállt a program. Példa ilyen hibákra: ─ ArrayBoundsOfException (tömb.
A KÖVETKEZŐKBEN SZÁMOZOTT KÉRDÉSEKET VAGY KÉPEKET LÁT SZÁMOZOTT KÉPLETEKKEL. ÍRJA A SZÁMOZOTT KÉRDÉSRE ADOTT VÁLASZT, VAGY A SZÁMOZOTT KÉPLET NEVÉT A VÁLASZÍV.
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 1. gyakorlat.
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 1. gyakorlat.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás I. 7. gyakorlat.
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 6. gyakorlat.
Fejlett Webes Technológiák II. Bilicki Vilmos
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 7. gyakorlat.
TÁMOP /1-2F JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam Osztályok, objektumok definiálása és alkalmazása. Saját.
Fejlett Programozási Technikák 2.
Fejlett Webes Technológiák
Párhuzamos programozás
Hernyák Zoltán Magasszintű Programozási Nyelvek I.
Fejlett Programozási Technikák 2.
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
Függvénysablonok használata
Előadás másolata:

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

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

Források New Features and Enhancements J2SE 5.0 (http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html ) http://www.langer.camelot.de/Resources/Links/JavaGenerics.htm Thinking in Java, 3rd Edition (http://mindview.net/Books/TIJ/DownloadSites) Error Handling with Exceptions Concurrency

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

Ú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

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<Integer> myIntList = new LinkedList<Integer>(); // 1’ myIntList.add(new Integer(0)); //2’ Integer x = myIntList.iterator().next(); // 3’

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

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 @deprecated 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 (@interface) Ha nincs adattagja akkor használatánál elhagyhatjuk a zárójeleket @AdattagNelkul public class TimeTravel { ... }

Példa public @interface RequestForEnhancement { int id(); String synopsis(); String engineer() default "[unassigned]"; String date(); default "[unimplemented]"; } @RequestForEnhancement( id = 2868724, synopsis = "Enable time-travel", engineer = "Mr. Peabody", date = "4/1/3007" ) public static void travelThroughTime(Date destination) { ... }

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

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

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

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)

Megoldások Basic: C++: Java: on error goto Az Ada nyelv hibakezelésén alapul Java: A C++ hibakezelésén alapul

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

Típusok Throwable: Error (fordításkori és rendszer hibák) Exception RunTimeException

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();

Kivétel argumentum Két konstruktorunk van: Throwable ős osztály default string argumentummal rendelkező throw new NullPointerException("t = null"); Throwable ős osztály

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 }

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)

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!"); }); } ///:~

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(); g(); }); } ///:~ Throwing MyException from f() MyException FullConstructors.f (.*) FullConstructors.main(.*) Throwing MyException from g() MyException: Originated in g() FullConstructors.g(.*)

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();

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 {

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"); }

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(.*)

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; }

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 { g(); System.err.println( "Caught in main, 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() 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() at Rethrowing.g(Rethrowing.java:18)

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( ) )

Példa public Object setField(String id, Object value) throws DynamicFieldsException { if(value == null) { DynamicFieldsException dfe = new DynamicFieldsException(); dfe.initCause(new NullPointerException()); throw dfe; }

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

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)

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!

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

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

Probléma class VeryImportantException extends Exception { public String toString() { return "A very important exception!"; } class HoHumException extends Exception { 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(); } ///:~ Probléma Exception in thread "main" A trivial exception", LostMessage.dispose(LostMessage.java:24) LostMessage.main(LostMessage.java:31)

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

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 …

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

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()); } }

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

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());

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

A szál életciklusa done sleeping blokkolt suspend sleep új resume start futtatható wait notify run metódus kilép halott stop

Állapotok I. új szál runnable 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)

Állapotok II. 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 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.

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()); } }

A run metódus kezelése II. 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;

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)

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 < 1000000; c++); System.out.println(i + " " + SimpleThread.getName()); System.out.println("DONE! " + SimpleThread.getName()); Példa:

Egyforma prioritás public class ThreeThreadsTest { 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 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(); }

Különböző prioritás public class ThreeThreadsTest { 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 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(); }

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

Daemon thread Háttérben fut Amikor minden szál véget ér akkor ő is befejezi tevékenységét setDaemon() isDaemon()

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

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(); } } ///:~

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

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(); } } ///:~

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

Példa: Tároló objektum: Tarolo Adat forrás: Producer Adat nyelő: Consumer main: PTest

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) { System.out.println("Irogatok"); contents = value; available = true; notifyAll(); Tarolo.java

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) { }

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);

Main 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(); }

Eredmény H:\>java PTest Irogatok Olvasgatok Consumer #1 kiolvastam: 0 Producer #1 beirtam: 0 …. Producer #1 beirtam: 8 Consumer #1 kiolvastam: 8 Producer #1 beirtam: 9 Consumer #1 kiolvastam: 9

Újrafoglalás public class Reentrant { public synchronized void a() { System.out.println("here I am, in a()"); } public synchronized void b() { System.out.println("here I am, in b()");

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

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

A következő előadás tartalma ANT JUnit CVS Log4J