Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Fronty (Queue) v JDK 1.5 (1.6) Java.vse.cz.

Podobné prezentace


Prezentace na téma: "Fronty (Queue) v JDK 1.5 (1.6) Java.vse.cz."— Transkript prezentace:

1 Fronty (Queue) v JDK 1.5 (1.6) Java.vse.cz

2 Knihovny, které jsou nepostradatelné
java.util.concurrent java.util.concurrent.atomic java.util.concurrent.locks

3 Popis knihoven Ve verzi 1.5 jazyka Java byly přidány nové třídy pro konkurenční programování, které vycházejí z myšlenek Douga Leaho (kniha Concurrent Programming in Java). Obsahují tři hlavní balíčky: java.util.concurrent – Obsahuje prostředky pro vytváření poolů (Executor, Callable, Future) včetně implementace jednoduchého ThreadPoolu, dále implementace konkurenčních front, map, množin a seznamů (poskytují vyšší výkon při konkurenčním přístupu), podpora pro časování s jemnou granularitou a nové synchronizační prostředky (Semaphore, Exchange a podobně). java.util.concurrent.atomic – Jednoduché proměnné s atomickým přístupem (AtomicBoolean, AtomicInteger, AtomicLong, AtomicReference, AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray …) java.util.concurrent.locks – Sada rozhraní pro lepší práci se zámky: Lock, ReadWriteLock, Condition.

4 Od verze 5 Nový balíček java.util.concurrent Tento balíček obsahuje třídy pro bezpečnou a pohodlnou práci v prostředí multithread(více vláknových) aplikací Implementována bez významného použití synchronized sekcí=> nedochází k tomu, že by vlákna zbytečně stály a nebo čekaly na zámek. obsahují třídy pro paralelní přístup k datům, zámky, semafory,... Od Javy 5.0 je totiž možné využít neblokující algoritmy.

5 Fronta Kolekce slouží k uchování elementů před zpracováním.
Kromě základních operací s kolekcemi nabízí fronty další operace jako přidávání, vybíraní a „inspekci“. Elementy ve frontě jsou obvykle řazeny systémem FIFO (first-in-first-out). Vyjímku tvoří tzv. priority queues(„prioritní fronty“), které řadí prvky podle to, jaký jim nastavíme comparator, připadně podle defaultního řazení pro daný typ. Další výjimkou jsou LIFO fronty(haldy), které, jak už název napovídá, řadí elementy způsobem LIFO (last-in-first-out).

6 Rozhraní BlockingQueue (Chránicí Fronta)
Součastí java.util.concurrent Dědí z tříd: java.until.Queue a java.util.Collection využívá implementace tříd java.util.concurrent umožňuje čekat na položku (např: podle priority, nebo časového intervalu) Toto je zajištěno pomocí těchto implementací: LinkedBlockingQueue ArrayBlockingQueue SynchronousQueue PriorityBlockingQueue DelayQueue Příklad instance BlockingQueue q = new SynchronousQueue(); BlockingQueue je z mnoha

7 Popis jednotlivých implementací
LinkedBlockingQueue - neomezená délka fronty, FIFO PriorityBlockingQueue - přerovnává položky dle priority ArrayBlockingQueue - pevná délka fronty, o to efektivnější SynchronousQueue - fronta nulové délky, nikdy neobsahuje žádnou položku, k výměně jedné položky se musí sejít producent i konzument, přijde-li dříve producent, čeká na konzumenta a naopak DelayQueue - položky přerovnává podle jejich timeoutu, ven je pustí až timeout doběhne, metoda size() sice může vrátit nějaké číslo, jakožto počet položek, ale neznamená to že už vypršel timeout a jsou tedy k dispozici).

8 Některé Metody Rozhraní BlockingQueue
put(E e ) - vloží určitou položku do fronty a nebo čeká dokud se neuvolní místo, při volání je nutné odchytit vyjimkou InterruptedException take() – vrací a maže aktuálně vybranou položku a nebo čeká až bude daná položka dostupná + vyjimka InterruptedException offer(E e) – přidání položky do fronty s tím, že pokud je možné položku přidat do fronty vrátí true a pokud ne, tak false poll(long timeout, TimeUnit unit) – vrátí a odebere vrchol fronty, pokud nelze vrátí null, zde se nastavuje i interval jak dlouho se má čekat na danou položku až bude dostupná. add(E e) – umožňuje přidat danou položku do fronty pokud je to možné a pokud ne je použita vyjímka IllegalStateException remove(Object o) – vymaže jednu danou instanci z fronty Dále například metody(které pochází už z dané implementace): size() – velikost fronty clear() – smaže vše ve frontě …. a další Další metody zděděné z java.util.Queue: element, peek, poll, remove

9 Příklad: producent a konzument Třída main:
package Queue; import java.util.concurrent.*; public class main { public static void main(String[] args) { BlockingQueue q = new SynchronousQueue(); Producent p = new Producent(q); Konzument c = new Konzument(q); Thread vlakno1 = new Thread(p); Thread vlakno2 = new Thread(c); vlakno1.start(); vlakno2.start(); }

10 Třída producent: package Queue; import java.util.Random;
import java.util.concurrent.BlockingQueue; public class Producent implements Runnable { private final BlockingQueue fronta; private Random generator; public Producent(BlockingQueue q) { fronta = q; //vlozeni fronty s danou implementaci generator = new Random(); } public void run() { try { while(true) { fronta.put(produkuje()); //u fronty se provede metoda put(), ktera prida polozku } catch (InterruptedException ex) { ex.printStackTrace(); private int produkuje() { int nahoda = generator.nextInt(30); System.out.println("přidá:" + nahoda); System.out.println("velikost fronty: " + fronta.size()); return nahoda;

11 Třída Konzument: package Queue;
import java.util.concurrent.BlockingQueue; public class Konzument implements Runnable { private final BlockingQueue fronta; public Konzument(BlockingQueue q) { fronta = q; //vlozeni fronty s danou implementaci } public void run() { try { while(true) { konzumovat(fronta.take()); //u fronty se provede metoda take(), ktera vrati polozku a pote odstrani System.out.println("velikost fronty: " + fronta.size()); } catch (InterruptedException ex) { ex.printStackTrace(); private void konzumovat(Object x) { System.out.println("veme:" + x); Závěr: třída BlockingQueue umí bezpečně používat více producentů a konzumentů

12 ArrayBlockingQueue Část výpisu pří použití ArrayBlockingQueue s parametrem 10: velikost fronty: 5 přidá:9 velikost fronty: 6 přidá:18 velikost fronty: 7 přidá:7 velikost fronty: 8 přidá:13 velikost fronty: 9 přidá:21 velikost fronty: 10 veme:18 veme:20 veme:19 Maximální velikost fronty je 10.

13 SynchronousQueue Část výpisu pří použití SynchronousQueue : veme:12
velikost fronty: 0 přidá:24 přidá:11 veme:24 veme:11 přidá:16 veme:16 přidá:0 Zde je vidět, že konzument vždy čeká na producenta a naopak a velikost fronty je 0.

14 LinkedBlockingQueue Část výpisu pří použití LinkedBlockinQueue:
přidá:28 velikost fronty: 7630 přidá:29 velikost fronty: 7631 velikost fronty: 7632 přidá:26 velikost fronty: 7633 velikost fronty: 7634 přidá:12 velikost fronty: 7635 přidá:16 velikost fronty: 7636 přidá:10 velikost fronty: 7637 přidá:22 velikost fronty: 7638 Neomezená velikost fronty.

15 Třída ConcurrentLinkedQueue (thread-safe, ale i paralelní fronta)
Fronta ConcurrentLinkedQueue může mít více producentů i konzumentů. Podobná „BlockingQueue“.

16 CAS- Compare-And-Swap
CAS je instrukce, která má tří argumenty paměťové místo M, předpokládanou hodnotu A a novou hodnotu B - CAS(M, A, B). Instrukce udělá to, že se podívá do paměti na místo M, z něj si přečte aktuální hodnotu, kterou porovná s předpokládanou hodnotou A. Pokud jsou stejné, nastaví na místo M novou hodnotu B, pokud se hodnoty nerovnají, neprovede se nic. To podstatné co zbývá o CAS instrukci říct je, že se jedná o atomickou instrukci. Nemůže tak nastat případ, kdy dvě vlákna paralelně mění jedno paměťové místo. Je tak vyloučeno, že by mohlo dojít k tomu, že se ve vláknu X provede porovnání aktuální a předpokládané hodnoty a před nastavením nové hodnoty by vlákno Y tuto hodnotu změnilo

17 Rozdíl mezi CAS a synchronized
Sémantika CAS instrukce je v podstatě stejná jako synchronized s tím rozdílem, že je to na úrovni hardwaru namísto JVM. Z toho vyplývá mnohem lepší výkonnost. Podpora CAS instrukce byla přidána od Javy 5.0 a v API je zpřístupněna v rámci package java.util.concurrent.atomic, kde jsou různá primitiva jako například AtomicInteger či AtomicReference, která modelují CAS instrukci pro různé datové typy. Díky CAS je možné nahradit synchronizaci a to tak, že implementace využije optimistický přístup.

18 Jak nahradit? Zde je příklad:
Představme si jednoduchý counter implementovaný pomocí synchronized bloku. publi class Counter { private int counter; public synchronized int inc() { return counter++; } Oproti tomu s využitím AtomicIntegeru. private final AtomicInteger counter = new AtomicInteger(); public int inc() { return counter.incrementAndGet();

19 Ještě jedna fronta sun.misc.Queue Lze použít jako střídaní zámku.
Používá synchronizovaní. Méně efektivní, než je CAS Nelze se na ní spoléhat V dalších verzí možná nebude.

20 Metody třídy Queue enqueue(Object obj);
dequeue() – metoda vrací nejstarší objekt ve frontě dequeue(long timeOut) metoda vrací Object, který je nejdéle ve frontě. Parametrem je čas, do kdy čeká na příchod objektu. isEmpty() –vrací True nebo False elements() reverseElements();

21 Přechody mezi stavy vlákna
new new thread start Ve frontě. Možné řešení: Wait, sleep, notify runnable Přidělen procesor yield blocked running Metoda „run“ skončí dead

22 Zdroje:

23 Děkujeme za pozornost! Má někdo nějaký dotaz?
Diskuze Děkujeme za pozornost! Má někdo nějaký dotaz?


Stáhnout ppt "Fronty (Queue) v JDK 1.5 (1.6) Java.vse.cz."

Podobné prezentace


Reklamy Google