1 / 27

Konkurentn é programovanie v JAVE

Franti šek Galčík. Konkurentn é programovanie v JAVE. Príklad na úvod. Jednoduchá GUI aplikácia Dlho trvajúca akcia blokuje hlavný „tok vykonávania príkazov“ v programe: pomalé I /O, sie ťová komunikácia (download z Internetu) d lho trvajúci výpočet

ryder
Télécharger la présentation

Konkurentn é programovanie v JAVE

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. František Galčík Konkurentnéprogramovaniev JAVE

  2. Príklad na úvod • Jednoduchá GUI aplikácia • Dlho trvajúca akcia blokuje hlavný „tok vykonávania príkazov“ v programe: • pomalé I/O, sieťová komunikácia (download z Internetu) • dlho trvajúci výpočet • Jednoduché riešenie: Vytvoriť “podproces” súbežne bežiaci s hlavným programom, ktorý bude zdieľať s hlavným programom haldu (“svet, v ktorom žijú objekty”)

  3. Vlákno - Thread • Simultálne bežiaca podúloha • Každá aplikácia má aspoň jedno vlákno, ktoré sa vytvorí pri štarte aplikácie a v ktorom sa začne vykonávať „main“

  4. Vytvorenie vlákna • Vlákna môžu vytvárať nové vlákna • Kľúčová trieda:java.lang.Thread • 2 základné spôsoby vytvorenia vlákna: • Rozšírením triedy Thread a prekrytím metódy run • Implementovaním rozhrania Runnable • Akcie, ktoré má (súbežne) vykonať vlákno sú definované v metóde run() • Po vykonaní metódy run() vlákno prestáva existovať(objekt triedy Thread reprezentujúci vlákno však môže existovať ďalej) • Vykonávanie vlákna sa štartuje metódou start()

  5. Príklad vytvorenia vlákna • Vytvorenie vlákna rozšírením triedy Thread: • Vytvoríme vlákno, ktoré bude zadaný čas vypisovať určený text pomocou objektu „vypisovača“ • Vytvorenie vlákna implementovaním rozhrania Runnable • Pozastavenievykonávania vlákna na stavovený čas: • Thread.sleep(…);

  6. Čo nám ponúka trieda Thread • Vlákno patrí do nejakej ThreadGroup • Skupinové riadenie vlákien • Vlákno môže pristupovať len k vláknam zo svojej ThreadGroup a jeho podskupín • Stromová hierarchia skupín • 2 druhy vlákien: • Používateľské (User) • Daemon(setDaemon, isDaemon) • Aplikácia končí, keď skončia všetky užívateľské vlákna (za daemonmi sa nečaká)

  7. Čo nám ponúka trieda Thread • Riadenie priority vlákna (setPriority/getPriority): • 1 najnižšia, 5 default, 10 najvyššia • Nastavenie ClassLoadera pre dané vlákno • Statická metóda Thread.currentThread() • Vráti referenciu na objekty triedy Thread, reprezentujúci bežiace vlákno • Užitočné pre vlákna vzniknuté implementovaním Runnable

  8. Ako predčasne ukončiť vlákno ? • Java neponúka možnosť predčasného ukončenia vlákna • Je možné poslať vláknu požiadavku na ukončenie: metóda interrupt() • Vlákno informáciu o požiadavke zistí: • Získaním informácie metódou isInterrupted() alebo interrupted() • Vznikom výnimky InterruptedException počas operácií, kedy je vlákno „uspané“

  9. Kooperácia medzi vláknami • Zasielanie požiadaviek (nastavenie príznaku) na ukončenia • Metóda t.join(): pozastaví vykonávanie vlákna, až kým vlákno t neskončí • Príklad: Ako to vyzerá, keď vlákna nefungujú tak, ako majú....

  10. Vlákien je veľa a procesorov málo • V určitom okamihu môže bežať najviac toľko vlákien, koľko máme k dispozícii procesorov • Ilúzia súbežného behu: time-slicing

  11. Vlákna a pamäť • Každé vlákno: • má svoj vlastný stack, kde sú uložené lokálne premenné • zdieľa heap, kde sú vytvárané objekty

  12. Problémy synchronizácie

  13. Monitory • Monitory zabezpečujú pre vlákna: • vzájomné vylúčenie(mutual exclusion) • kooperáciu • S každým objektom je asociovaný monitor • Monitor kontroluje vykonávanie istých častí kódu: kritických sekcií asociovaných s monitorom • V každom okamihu môže vlastniť monitor (vykonávať kód kritickej sekcie monitora)nanajvýš jedno vlákno

  14. Monitory v kóde synchronized (objekt) { .... kód kritickej sekcie monitora asociovaného s objektom objekt ... } • Ak chceme synchronizovať celý kód metódy voči monitoru asociovanému objektu this, stačí pridať „synchronized“ ku hlavičke inštančnej metódy

  15. Problém producenta a konzumenta • Sklad s obmedzenou kapacitou • Producent produkuje položky a vkladá ich do skladu, ak je v sklade voľné miesto • Konzument vyberá zo skladu a konzumuje, ak je v sklade nejaká položka Riešenie bez kooperácie: • Vlákno producent a konzumer sú synchronizovanémonitorom asociovaným s objektom skladu: v každom okamihu je iba jeden z nich vo vnútri skladu • Ak sa sklad vyprázdni, konzument musí pravidelne zazerať do skladu, či je ešte stále prázdny – činnéčakanie na príchod novej položky

  16. Kooperácia vlákien • Podpora kooperácie (eliminácia činného čakania na splnenie podmienky): • wait() – vlákno v kritickej sekcii sa vzdá monitora dovtedy, kým od iného vlákna nepríjme notifikáciu • notify(), notifyAll() – vlákno v kritickej sekcii oznáminejakému čakajúcemu vláknu, resp. čakajúcim vláknam, že môžu v kritickej sekcii pokračovať • wait(), notify(), notifyAll() sú inštančné metódy objektu, s ktorým je asociovaný monitor

  17. Algoritmus konzumenta while (true) { synchronized (sklad) { // Kym niet v sklade ziadnej polozky // cakame za notifikaciou while (!sklad.hasItem()) sklad.wait(); // Skonzumujeme polozku consume(sklad.getItem()); // Ak niekto (producent) caka za uvolnenim // miesta v sklade, tak mu posleme notifikaciu sklad.notify(); } }

  18. Schéma fungovania monitorov

  19. Volatile premenné • volatile označuje premenné, ktoré môžu byť modifikované viacerými vláknami a inštruuje procesor, aby vždy použil hodnotu „aktuálnu“ hodnotu namiesto hodnoty cachovanej v registroch public void doWork() { while (!shutdownRequested) processing(); }

  20. Vlákna v JVM • “Green Threads” • do verzie 1.1 jediný mechanizmus riadenia vlákien • kooperatívny multitasking • JVM simuluje viacero vlákien v jednom vlákne • Od verzie 1.2 využívanie vlákien OS • Monitory: • Inštrukcie v byte-code(monitorenter, monitorexit) • Ku každému objektu je priradené počítadlo počítajúce počet vstupov vlákna do kritickej sekcie asociovaného monitora

  21. Ďalšie užitočné triedy • ThreadLocal– objekt, ktorý pre každé vlákno uchováva špecifickú hodnotu • Timer • vytvára vlákno, do ktorého je možné vkladať úlohy ako objekty triedy TimerTask • vykonanie úlohy je možné naplánovať na určitý čas, resp. periodické vykonávanie • SwingTimer, SwingWorker– mechanizmus na podporu konkurencie v rámci Swing a vykonávania akcií v rámci Event Dispatch Threadu (jediný spôsob ako pracovať thread-safety so Swing-om)

  22. Java 1.5: Executor Framework • Problém: Ak potrebujeme vykonávať veľa krátkych súbežných úloh, tak vytvorenie vlákna sa stane drahou operáciou • Riešenie: Budeme udržiavať „pool” vlákien a ak príde nová úloha, tak použijeme nejaké voľné vlákno • Executors: továreň Executorov • newSingleThreadExecutor() • newFixedThreadPool() • newCachedThreadPool() • newScheduledThreadPool()

  23. publicclass WebServer { static Executor pool = Executors.newFixedThreadPool(7); publicstaticvoid main(String[] args) { ServerSocket socket = new ServerSocket(80); while (true) { final Socket connection = socket.accept(); Runnable r = new Runnable() { publicvoid run() { handleRequest(connection); } }; pool.execute(r); } } }

  24. Java 1.5: Callable, Future • Problém: neexistuje jednoduchý spôsob ako vytvoriť súbežnú úlohu, ktorá vráti výsledok iným vláknam • Riešenie: • Executor má metódu submit, ktorou ide odoslať na vykonanie úlohu • Úloha je preprezentovaná ako implementácia rozhrania Callable<V>… metóda V call() • Výsledkom volania submit je implementácia rozhrania Future<V>, ktoré poskytuje metódu get() na získanie výsledku vykonania úlohy

  25. Java 1.5: Lepšia synchronizácia • Problém: systém monitorov je obmedzený, dovoľuje len hierarchické získavanie monitorov (zámkov) • Riešenie: • Semaphore: acquire/release • java.util.locks: Lock, Condition, ReadWriteLock, ReentrantLock, ReentrantReadWriteLock • Lock: lock/unlock • Synchronizované kolekcie: ArrayBlockingQueue • Atomické premenné

  26. Java 1.5: Lepšia koordinácia • CountDownLatch: umožňuje pozastaviť vlákna, kým sa nevykoná určitá množina operácií (countDown, await) • CyclicBarrier: umožnuje pozastaviť vlákna, kým zadaný počet vlákien nedosiahne definovanú bariéru (await)

  27. Ďakujem za pozornosť.

More Related