1 / 26

Nachdenken in Aurich 2009

Nachdenken in Aurich 2009. Threadnocchio Spielerisches Erlernen der parallelen Programmierung mit Java-Threads. Dietrich Boles. Gliederung. Java-Threads vor Java 5 Threads Scheduling syncronized wait-notify Java-Threads seit Java 5 Sperren Atomare Variablen Queues

anoush
Download Presentation

Nachdenken in Aurich 2009

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. Nachdenken in Aurich 2009 Threadnocchio Spielerisches Erlernen der parallelen Programmierung mit Java-Threads Dietrich Boles

  2. Gliederung • Java-Threads vor Java 5 • Threads • Scheduling • syncronized • wait-notify • Java-Threads seit Java 5 • Sperren • Atomare Variablen • Queues • Nützliche Synchronisationsklassen • Thread-Pools • Einführung in das Arbeiten mit Threadnocchio • Praktisches Arbeiten mit Threadnocchio

  3. Java-Threads Klasse java.lang.Thread public class ThreadKlasse extends Thread { private String str; public ThreadKlasse(String s) { this.str = s; } public void run() { while (true) System.out.println(this.str); } public static void main(String[] args) { ThreadKlasse hallo = new ThreadKlasse("hallo"); ThreadKlasse dibo = new ThreadKlasse("dibo"); hallo.start(); dibo.start(); } } ( 1-threads-startrek)

  4. Thread-Zustände blockiert deblockieren (synchronized-Ende, sleep-Ende, Thread-Ende, notify, EA-Ende, interrupt) blockieren (synchronized, sleep, join, wait, EA) zuordnen erzeugt bereit beendet rechnend start() Ende von run verdrängen, yield()

  5. Scheduling • static int activeCount() • static int enumerate(Thread[] tarray) • static Thread currentThread() • Thread.State getState() // NEW, TERMINATED, WAITING, … • void setPriority(int priority) // wenig sinnvoll • int MIN_PRIORITY, int MAX_PRIORITY, int NORM_PRIORITY • static void yield() // in Zustand bereit • static void sleep(long milliSekunden) // blockieren • void join() // auf Ende warten • void interrupt() // sleep, join unterbrechen • void setDaemon(boolean on) // Garbage-Collector

  6. Kommunikation • Kommunikation = Datenaustausch • über gemeinsame Variablen bzw. Objekte möglich, da sich Threads einen gemeinsamen Adressraum teilen • Probleme bei der Nutzung gemeinsamer Variablen • Nicht-determinierte Ergebnisse durch Races (Wettrennen) • Schreib/Schreibkonflikte • Schreib/Lesekonflikte • „Kritische Abschnitte“ • Lösung: • Synchronisation = Ordnung der Abfolge bestimmter Aktivitäten mehrerer Threads • Synchronisationsarten: • mehrseitige Synchronisation • einseitige Synchronisation

  7. synchronized • jedes Objekt besitzt Sperre (Lock) • Sperren können implizit gesetzt bzw. freigegeben werden • synchronized-Anweisung: synchronized (<Objektreferenz>) // Sperr-Objekt <Anweisung> // Kritischer Abschnitt • synchronized-Methoden synchronized void m() { /* krit Abschnitt */ } entspricht: void m() { synchronized (this) { /* krit Abschnitt */ } }  2-mssync-elefanten

  8. wait-notify (1) • Problem: Bestimmte Anweisungen sollen nur dann ausgeführt werden, wenn anwendungsabhängige Bedingungen erfüllt sind; ansonsten warten (und zwar nicht aktiv!) public class Object { public final void wait() // passives Warten public final void notify() // wecken (eines Threads) public final void notifyAll() // wecken aller }

  9. wait-notify (2) synchronized (obj) { while (!bedingung) obj.wait(); } • Voraussetzung: Lock von obj ist gesetzt ( synchronized) • Aufrufender Thread wird blockiert • Lock von obj wird frei gegeben synchronized (obj) { bedingung erfüllen; obj.notify(); } • Voraussetzung: Lock von obj ist gesetzt ( synchronized) • Irgendein Thread T1, der auf obj wartet, wird in den Zustand bereit versetzt (notifyAll  alle) • T1 muss erst wieder Lock setzen, bevor er fortfahren kann  3-essync-baby

  10. Semaphore (1) • Java: synchronized-Anweisung • Nachteile: • Block-gebunden • Kein Hand-over-Locking möglich • Thread-gebunden • Exklusiv • Lösung: Semaphore // Thread 1 // Thread 2 sem.p(); sem.p(); // kritischer Abschnitt // kritischer Abschnitt sem.v(); sem.v();

  11. Semaphore (2) public class Semaphor { private int freiePlaetze; public Semaphor(int maximalFreiePlaetze) { if (maximalFreiePlaetze < 0) this.freiePlaetze = 0; else this.freiePlaetze = maximalFreiePlaetze; } public synchronized void p() { while (this.freiePlaetze == 0) { try { this.wait(); } catch (InterruptedException exc) {} } this.freiePlaetze--; } public synchronized void v() { this.freiePlaetze++; this.notify(); } }

  12. Semaphore (3) package java.util.concurrent; class Semaphore { // seit Java 5 public Semaphore(int permits) public Semaphore(int permits, boolean fair) public void acquire() throws InterruptedException public void acquireUninterruptibly() // p public boolean tryAcquire() public void release() // v ... }  4-semaphore-elefanten

  13. Locks(1) • synchronized: implizite Sperren • Locks: explizite Sperren (seit Java 5) public interface Lock { public void lock(); public void unlock(); public Condition newCondition() } public interface Condition { public void await() throws InterruptedException public void signal() public void signalAll() } public class ReentrantLock implements Lock { ... }

  14. Locks(2) Lock sperre = new ReentrantLock(); Condition bedingung = sperre.newCondition(); sperre.lock(); try { ... bedingung.await(); // auf Erfülltsein warten } finally { sperre.unlock(); } sperre.lock(); try { ... bedingung.signal(); // Erfülltsein signalisieren } finally { sperre.unlock(); }  5-locks-baby

  15. ReadWriteLocks • ReadWriteLocks: Lösung für Reader-Writer-Problem • 2 Locks: • ReadLock: mehrere Threads • WriteLock: exklusive Sperre public interface ReadWriteLock { public Lock readLock() public Lock writeLock() } public class ReentrantReadWriteLock implements ReadWriteLock  6-rwlocks-elefanten

  16. Atomare Variablen (1) • Klassen für atomare Variablen der Standarddatentypen • keine Sperren notwendig class Konto { int kontostand1 = 0; AtomicInteger kontostand2 = new AtomicInteger(0); synchronized int einzahlen1(int betrag) { return kontostand1 = kontostand1 + betrag; } int einzahlen2(int betrag) { return this.kontostand.addAndGet(betrag); } }

  17. Atomare Variablen (2) package java.util.concurrent.atomic; public class AtomicInteger extends java.lang.Number { public AtomicInteger(int initialValue) public final void set(int newValue) public final int get() public final boolean compareAndSet(int exp, int update) public final int addAndGet(int delta) public final int getAndIncrement() public final int getAndDecrement() public final int getAndAdd(int delta) ... }

  18. Queues • Interfaces • Queue (add, element, remove, …) • BlockingQueue (put, poll, …) • Deque (addFirst, addLast, …) • BlockingDeque (offerFirst, offerLast, …) • Klassen • ArrayBlockingQueue<E> (begrenzt) • LinkedBlockingQueue<E> (unbegrenzt) • LinkedBlockingDeque<E> (unbegrenzt) • SynchronousQueue<E> (Übergabe on-the-fly) • PriorityBlockingQueue<E> (Lieferung gemäß Prioritäten) • DelayQueue<E extends Delayed> (Objekte bestimmen Verweildauer) • …  7-queues-baby

  19. Exchanger • Welchselseitiger Austausch von Objekten zwischen Threads package java.util.concurrent; public class Exchanger<V> { public Exchanger() public V exchange(V data) throws InterruptedException }  8-exchanger-baby (ohne Lösung)

  20. CountDownLatch • Realisierung von Count-Downs package java.util.concurrent; public class CountDownLatch { public CountDownLatch(int initCount) public void await() throws InterruptedException public void countDown() ... }  9-countdown-animals

  21. CyclicBarrier • Realisierung von Sammelpunkten package java.util.concurrent; class CyclicBarrier { public CyclicBarrier(int anzahl) public int await() throws InterruptedException, BrokenBarrierException ... }  10-barriers-animals

  22. FutureTask • Threads, die Ergebnisse liefern public interface Callable<V> { public V call() throws Exception; } public class FutureTask<V> implements Runnable { public FutureTask(Callable<V> callable) public V get() throws InterruptedException, ExecutionException // ... }

  23. Thread-Pooling (1) • Threads „auf Vorrat“ class ThreadPoolExecutor implements ExecutorService { public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) public void execute(Runnable command) ... } public class Executors { public static ExecutorService newCachedThreadPool() public static ExecutorService newFixedThreadPool(int maxThreads) // ... }

  24. Thread-Pooling (2) int ANZAHL_AUFTRAEGE = 5; int ANZAHL_GLEICHZ_THREADS = 2; ExecutorService dienstleister = Executors .newFixedThreadPool(ANZAHL_GLEICHZ_THREADS); for (int i = 0; i < ANZAHL_AUFTRAEGE; i++) { dienstleister.execute(<Runnable.auftrag>); } dienstleister.shutdown();

  25. Arbeiten mit Threadnocchio

  26. Aufgaben • Passt das Stück „Exchanger“ so an, dass Kauffrauen und Mütter an der Kasse Essen gegen Geld tauschen! • Versucht einmal, die Klasse Exchanger mit den Java-1.4-Standardmechanismen selbst zu implementieren!

More Related