Java-Praktikum Sonstiges Dietrich Boles Seite 1Threadnocchio Dietrich Boles
Nachdenken in Aurich 2009
Threadnocchio
Spielerisches Erlernen der parallelen Programmierung
mit Java-Threads
Dietrich Boles
Java-Praktikum Sonstiges Dietrich Boles Seite 2Threadnocchio Dietrich Boles
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
Java-Praktikum Sonstiges Dietrich Boles Seite 3Threadnocchio Dietrich Boles
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)
Java-Praktikum Sonstiges Dietrich Boles Seite 4Threadnocchio Dietrich Boles
Thread-Zustände
erzeugt bereit rechnend beendet
blockiert
start() Ende von run
zuordnen
verdrängen,yield()
blockieren(synchronized, sleep, join,wait, EA)
deblockieren(synchronized-Ende,sleep-Ende, Thread-Ende,notify, EA-Ende, interrupt)
Java-Praktikum Sonstiges Dietrich Boles Seite 5Threadnocchio Dietrich Boles
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
Java-Praktikum Sonstiges Dietrich Boles Seite 6Threadnocchio Dietrich Boles
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 Synchronisationeinseitige Synchronisation
Java-Praktikum Sonstiges Dietrich Boles Seite 7Threadnocchio Dietrich Boles
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
Java-Praktikum Sonstiges Dietrich Boles Seite 8Threadnocchio Dietrich Boles
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
}
Java-Praktikum Sonstiges Dietrich Boles Seite 9Threadnocchio Dietrich Boles
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
Java-Praktikum Sonstiges Dietrich Boles Seite 10Threadnocchio Dietrich Boles
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();
Java-Praktikum Sonstiges Dietrich Boles Seite 11Threadnocchio Dietrich Boles
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(); }}
Java-Praktikum Sonstiges Dietrich Boles Seite 12Threadnocchio Dietrich Boles
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
Java-Praktikum Sonstiges Dietrich Boles Seite 13Threadnocchio Dietrich Boles
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 { ... }
Java-Praktikum Sonstiges Dietrich Boles Seite 14Threadnocchio Dietrich Boles
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
Java-Praktikum Sonstiges Dietrich Boles Seite 15Threadnocchio Dietrich Boles
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
Java-Praktikum Sonstiges Dietrich Boles Seite 16Threadnocchio Dietrich Boles
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);
}
}
Java-Praktikum Sonstiges Dietrich Boles Seite 17Threadnocchio Dietrich Boles
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)
...
}
Java-Praktikum Sonstiges Dietrich Boles Seite 18Threadnocchio Dietrich Boles
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
Java-Praktikum Sonstiges Dietrich Boles Seite 19Threadnocchio Dietrich Boles
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)
Java-Praktikum Sonstiges Dietrich Boles Seite 20Threadnocchio Dietrich Boles
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
Java-Praktikum Sonstiges Dietrich Boles Seite 21Threadnocchio Dietrich Boles
CyclicBarrier
Realisierung von Sammelpunkten
package java.util.concurrent;
class CyclicBarrier {
public CyclicBarrier(int anzahl)
public int await() throws InterruptedException,
BrokenBarrierException
...
}
10-barriers-animals
Java-Praktikum Sonstiges Dietrich Boles Seite 22Threadnocchio Dietrich Boles
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
// ...
}
Java-Praktikum Sonstiges Dietrich Boles Seite 23Threadnocchio Dietrich Boles
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)
// ...
}
Java-Praktikum Sonstiges Dietrich Boles Seite 24Threadnocchio Dietrich Boles
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();
Java-Praktikum Sonstiges Dietrich Boles Seite 25Threadnocchio Dietrich Boles
Arbeiten mit Threadnocchio
Java-Praktikum Sonstiges Dietrich Boles Seite 26Threadnocchio Dietrich Boles
Aufgaben
1. Passt das Stück „Exchanger“ so an, dass Kauffrauen und Mütter an der Kasse Essen gegen Geld tauschen!
2. Versucht einmal, die Klasse Exchanger mit den Java-1.4-Standardmechanismen selbst zu implementieren!