Fejlett Programozási Technikák 2.

Slides:



Advertisements
Hasonló előadás
Fejlett Programozási Technikák 2.
Advertisements

Java programozási nyelv Filekezelés
Fejlett Webes Technológiák II. Bilicki Vilmos
FIATALOK LENDÜLETBEN PROGRAM Ruska Mónika – Mobilitás Országos Ifjúsági Szolgálat - Fiatalok Lendületben Programiroda.
Az Endnote bibliográfia adatbázis- kezelő szoftver alapvető használata 2013 Skultéti Attila
Bevezetés a C# nyelvbe Az alapok összefoglalása Farkas Csaba.
ISKOLAKÉSZÜLTSÉG – AZ ADAPTÍV VISELKEDÉS FEJLETTSÉGE dr. Torda Ágnes gyógypedagógus, klinikai gyermek-szakpszichológus Vizsgálóeljárás az iskolába lépéshez.
 Alap tudnivalók Alap tudnivalók  Az If és a While folyamatábrák Az If és a While folyamatábrák  Probléma Probléma  A while ciklus (általános alak,
1 Az önértékelés mint projekt 6. előadás 1 2 Az előadás tartalmi elemei  A projekt fogalma  A projektek elemei  A projekt szervezete  Projektfázisok.
BINARIT TIMESHEET Több, mint munkaidő nyilvántartás Virág Zsolt (BINARIT Informatikai Kft.)„Hogyan legyek milliomos?” konferencia – BKIK ( )
2. A szoftverek csoportosítása: a. Rendszerszoftverek: A számítógép zavartalan mûködését biztosítják: BIOS (alapvetõ bemeneti/kimeneti rendszer): olyan.
Forrás: Reiter István C_Sharp programozás lépésről lépésre (frissített tartalommal )
EU pályázati programok A szervezet / változások 1.A pályázók adminisztrációs terheinek csökkentése a projektfejlesztési, pályázati szakaszban.
Az Európai Unió fogyatékosügyi stratégiája Szombathely, június 22.
Internet tudományos használata
ERASMUS+ DISSZEMINÁCIÓS PLATFORM
Gazdasági informatika - bevezető
Fájlkezelés.
Munkalapok védelme az Excelben
Nagyméretű állományok küldése
Fejlett Programozási Technikák 2.
Fejlett Webes Technológiák
Operációs rendszerek.
Pályaválasztási tanácsadás
Alhálózat számítás Osztályok Kezdő Kezdete Vége Alapértelmezett CIDR bitek alhálózati maszk megfelelője A /8 B
Párhuzamos programozás
Java kódolási konvenciók
Scilab programozás alapjai
Foglalkoztatási Paktumok az EU-ban
videós team Team vezetője: Tariné Péter Judit Tagok:
Az Európai Uniós csatlakozás könyvtári kihívásai
Háttértárak karbantartása
LabVIEW bevezetéstől a feszültség-áram karakterisztikáig Vida Andrea
Tömörítés.
Downstream Power Back Off (DPBO)
Programozás I. Gyakorlás egydimenziós tömbökkel Többdimenziós tömbök
Kérdések és válaszok az előfizetéses rendszerekről
C# SZINTAKTIKÁJA Az egyes utasítások végén pontosvessző áll
Dependency Injection Moq Feladat
Animációk.
Adatbázis-kezelés (PL/SQL)
2. Bevezetés A programozásba
VB ADATTÍPUSOK.
Downstream Power Back Off (DPBO)
A számítógép operációs rendszere
Közigazgatási alapvizsga a Probono rendszerben
Rendszerfejlesztés gyakorlat
Számítógépes Hálózatok
Az Endnote bibliográfia adatbázis-kezelő szoftver alapvető használata november Skultéti Attila
CONTROLLING ÉS TELJESÍTMÉNYMENEDZSMENT DEBRECENI EGYETEM
IDŐZÍTÉS PROGRAMOZÁSA
3. A robot képernyőmenüje
Fejlett Webes Technológiák II.
Informatikai gyakorlatok 11. évfolyam
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
Szoftverrobotok vs biorobotok Bemutatkozik Albert, a vállalati robot
B M Java Programozás 4. Gy: Java GUI IT A N Tipper, MVC kalkulátor
Környezeti Kontrolling
Új pályainformációs eszközök - filmek
A távoli asztal, valamint az Endnote használata a távoli asztalon
B M Java Programozás 9. Gy: Java alapok IT A N Adatkezelő 5.rész
Szálszinkronizáció.
A szállítási probléma.
I. HELYZETFELMÉRÉSI SZINT FOLYAMATA 3. FEJLESZTÉSI FÁZIS 10. előadás
Cisco Router parancssoros konfigurálása
A számítógép operációs rendszere
B M Java Programozás 2. Gy: Java alapok IT A N Adatszerkezetek
SQL jogosultság-kezelés
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
Algoritmusok.
Előadás másolata:

Fejlett Programozási Technikák 2. 14/6

A mai előadás tartalma: Többszálúság I/O

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 …

Timer I. segítségével egy párhuzamos szálat indíthatunk mely adott időközönként lefuttatja a run metódust az alosztályt a Timer osztályból kell származtatnunk meg kell valósítanunk a run metódust amikor példányosítjuk akkor létrehozunk egy új szálat is, mely a schedule metódus segítségével elindítjuk

Timer II. System.out.println("Time's up!"); timer.cancel(); class RemindTask extends TimerTask { public void run() System.out.println("Time's up!"); timer.cancel(); } public static void main(String args[]) System.out.println("About to schedule task."); new Reminder(5); System.out.println("Task scheduled."); import java.util.Timer; import java.util.TimerTask; public class Reminder { Timer timer; public Reminder(int seconds) timer = new Timer(); timer.schedule(new RemindTask() , seconds*1000); }

Timer III. az időzítésre megadhatunk konkrét időpontot is: Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 1); calendar.set(Calendar.SECOND, 0); Date time = calendar.getTime(); timer = new Timer(); timer.schedule(new RemindTask(), time);

A Timer szál leállítása a cancel metódus meghívásával amennyiben daemon-ként futtatjuk akkor a program automatikusan, befejezi futását ha csak daemon szálak vannak (new Timer(true).). miután minden feladatát végrehajtotta, megszüntetve minden referenciát a Timer objektumra automatikusan befejezi ténykedését a System.exit metódus meghívásával az egész programból kiléphetünk

Példa: class RemindTask extends TimerTask import java.util.Timer; { int numWarningBeeps = 3; public void run() if (numWarningBeeps > 0) { toolkit.beep(); System.out.println("Beep!"); numWarningBeeps--; } else { toolkit.beep(); System.out.println("Time's up!"); System.exit(0); } } } public static void main(String args[]) { System.out.println("About to schedule task."); new AnnoyingBeep(); System.out.println("Task scheduled."); } } import java.util.Timer; import java.util.TimerTask; import java.awt.Toolkit; public class AnnoyingBeep { Toolkit toolkit; Timer timer; public AnnoyingBeep() { toolkit = Toolkit.getDefaultToolkit(); timer = new Timer(); timer.schedule(new RemindTask(), 0, 1*1000); }

Timer, schedule schedule( TimerTask feladat, long késleltetés, long periódus) schedule( TimerTask feladat, Date időpont, long periódus) scheduleAtFixedRate(TimerTask feladat, long késleltetés, long periódus) scheduleAtFixedRate(TimerTask feladat, Date első időpont, long periódus)

Thread osztály a Thread osztály egy általános szálat valósít meg mely nem csinál semmit a run metódus üres a run metódus felülírásával tudunk feladatot specifikálni 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 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 public class TwoThreadsDemo { public static void main (String[] args) new SimpleThread("Jamaica").start(); new SimpleThread("Fiji").start(); }

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

Szálak szinkronizálása 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

Zárolás synchronized 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.

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

Deadlock, éhezés ebédelő filozófusok nehéz észlelni a végtelen ciklusokat célszerű olyan szabályokat alkal- mazni melyekkel liküszöbölhetőek

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

Szál csoport metódusok ThreadGroup(Sting name) – konstruktor ThreadGroup(ThreadGroup parent ,Sting name) – konstruktor, itt az ős a parent csoport int activeCount() – a csoportban lévő aktív szálak számát adja vissza int enumerate(Thread[] list) – a csoportban lévő szálak hivatkozásait gyűjti össze TheradGroup getParent() – a szülő csoportot adja vissza void interrupt() – megszakítja minden szál munkáját

I/O írás, olvasás az információ írásához olvasásához csövekre van szükségünk java.io: karakter folyamok bájt folyamok

I/O – karakter folyamok 16 bites karakterek olvassák, írják a forrást valamilyen műveleteket végeznek rajta

I/O – bájt folyamok 8 bites egységek egyszerű folyamok feladat végző folyamok

Fájl folyamok FileReader FileWriter FileInputStream FileOutputStream public class Copy { public static void main(String[] args) throws IOException { File inputFile = new File("farrago.txt"); File outputFile = new File("outagain.txt"); FileReader in = new FileReader(inputFile); FileWriter out = new FileWriter(outputFile); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); } FileReader FileWriter FileInputStream FileOutputStream

Sor folyamok (Pipe streams) Arra szolgálnak, hogy összekössék egyik szál bemenő csatornáját a másik szál kimenő csatornájával. Az egyik szál beírja az adatokat a csatornába és nem foglalkozik vele tovább A másik kiolvassa Nem kell foglalkoznunk a szinkronizálással Metódusai: PipedReader PipedWriter PipedInputStream PipedOutputStream

Példa: RhymingWords ReverseThread SortThread

import java.io.*; public class RhymingWords { public static void main(String[] args) throws IOException { FileReader words = new FileReader("words.txt"); Reader rhymedWords = reverse(sort(reverse(words))); BufferedReader in = new BufferedReader(rhymedWords); String input; while ((input = in.readLine()) != null) System.out.println(input); in.close(); } public static Reader reverse(Reader source) throws IOException { BufferedReader in = new BufferedReader(source); PipedWriter pipeOut = new PipedWriter(); PipedReader pipeIn = new PipedReader(pipeOut); PrintWriter out = new PrintWriter(pipeOut); new ReverseThread(out, in).start(); return pipeIn; . . . folyt köv

public static Reader sort(Reader source) throws IOException { BufferedReader in = new BufferedReader(source); PipedWriter pipeOut = new PipedWriter(); PipedReader pipeIn = new PipedReader(pipeOut); PrintWriter out = new PrintWriter(pipeOut); new SortThread(out, in).start(); return pipeIn; }

import java.io.*; public class ReverseThread extends Thread { private PrintWriter out = null; private BufferedReader in = null; public ReverseThread(PrintWriter out, BufferedReader in) { this.out = out; this.in = in; } public void run() { if (out != null && in != null) { try { String input; while ((input = in.readLine()) != null) { out.println(reverseIt(input)); out.flush(); out.close(); } catch (IOException e) { System.err.println("ReverseThread run: " + e); } … folytatás

private String reverseIt(String source) { int i, len = source.length(); StringBuffer dest = new StringBuffer(len); for (i = (len - 1); i >= 0; i--) dest.append(source.charAt(i)); return dest.toString(); }

DataInputStream, DataOutputStream segítségével egyszerűen tudunk más sorokba olvasni, írni egyedül nem használható mindenképpen csatolni kell egy másik csőhöz

import java.io.*; public class DataIODemo { public static void main(String[] args) throws IOException { DataOutputStream out = new DataOutputStream(new FileOutputStream(”a1.txt")); double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 }; int[] units = { 12, 8, 13, 29, 50 }; String[] descs = { "Java T-shirt", "Java Mug", "Duke Juggling Dolls", "Java Pin", "Java Key Chain" }; for (int i = 0; i < prices.length; i ++) { out.writeDouble(prices[i]); out.writeChar('\t'); out.writeInt(units[i]); out.writeChars(descs[i]); out.writeChar('\n'); } out.close(); … folyt köv

DataInputStream in = new DataInputStream(new FileInputStream(”a1 DataInputStream in = new DataInputStream(new FileInputStream(”a1.txt")); double price; int unit; StringBuffer desc; double total = 0.0; try { while (true) { price = in.readDouble(); in.readChar(); // throws out the tab unit = in.readInt(); char chr; desc = new StringBuffer(20); char lineSep = System.getProperty("line.separator").charAt(0); while ((chr = in.readChar()) != lineSep) desc.append(chr); System.out.println("You've ordered " + unit + " units of " + desc + " at $" + price); total = total + unit * price; } } catch (EOFException e) {} System.out.println("For a TOTAL of: $" + total); in.close();

Véletlen hozzáférésű fájlok előfordul, hogy a fájl tartalmát nem sorban kell olvasnunk, hanem véletlen, tetszőleges sorrendben ilyen lehet egy .ZIP fájl melyben megkeressük az adott fájlt és azt kitömörítjük RandomAccessFile osztály: new RandomAccessFile("farrago.txt", "r"); new RandomAccessFile("farrago.txt", "rw"); int skipBytes(int) void seek(long) long getFilePointer()