Threads in Java Threads Sprachumfang von Java Der Java-Standard fordert nur die Unterstützung von Thread-Prioritäten. Es gibt keine Forderung bzgl.: –Verdrängendes/kooperierendes Umschalten –Zeitverteilungsstrategie (Round Robin etc.)
Benutzung von Threads Spezialisierung der Klasse java.lang.Thread Implementierung des Interface java.lang.Runnable Thread.start(): Asynchrone nebenläufige Ausführung von run() Class MyThread1 extends Thread {... public void run() {...}...} Class MyThread2 implements Runnable {... public void run() {...}...}.... MyThread1 mt1 = new MyThread1(); mt1.start(); MyThread2 mt2 = new MyThread2(); Thread thr = new Thread(mt2); thr.start();... Class MyThread1 extends Thread {... public void run() {...}...} Class MyThread2 implements Runnable {... public void run() {...}...}.... MyThread1 mt1 = new MyThread1(); mt1.start(); MyThread2 mt2 = new MyThread2(); Thread thr = new Thread(mt2); thr.start();...
Synchronisation mit Monitoren Monitore überwachen kritische Bereiche (KB): –KB ist Teil des Programmcodes –Höchstens ein Thread im KB Ablauf: –Anmeldung des Threads (T) beim Monitor (M) –T blockiert –Wenn KB frei ist Aktivierung von Tdurch M (T belegt M) –Wenn T KB verlässt Signalisierung an den Monitor (T gibt M frei)
Monitore in Java Jedes Java-Objekt ist ein Monitor. Syntax: synchronized (obj) {... Kritischer Bereich... } Spezialsyntax für kritische Methodenaufrufe: synchronized Type method(...) {...} entspricht Type method(...) { synchronized(this) {...} }
Explizite Synchronisation 3 Methoden zur Freigabe von Monitoren: –wait() Blockierung des Threads –notify() Deblockierung eines Threads des Monitors –notifyAll() Deblockierung aller Threads des Monitors
Lebenszyklus eines Threads (vereinfacht) sleeping blocked end runnablerunning Scheduler start() interrupt() sleep() wait(), join() notify(), Interrupt() Terminierung von run()
System besteht aus drei Objekten: –Producer erzeugt regelmäßig Daten, –Consumer verarbeitet diese Daten. –Datenspeicherung in einem Depot Es soll keine Rechenzeit vergeudet werden: –Keine Erzeugung bei vollem Depot. –Keine Consumer-Aktivität ohne Daten Aber: Nebenläufige Erzeugung/Verarbeitung Beispiel: Producer/Consumer ProducerDepotConsumer
Depot class Depot { private int buffer=-1; private boolean empty = true; synchronized int getContent() throws InterruptedException { while( empty) { wait(); } // warte bis gefüllt int res = buffer; empty = true; // kopiere Ergebnis notify(); // signalisiere leeres Depot return res; } synchronized void putContent( int content) throws InterruptedException { while ( ! empty ) { wait(); } // warte bis Depot leer buffer = content; empty = false;// fülle Depot notify();// signalisiere volles Depot return; } }
Producer class Producer extends Thread { private Depot myDepot; Producer( Depot dep) { myDepot = dep; } public void run() { int i = 0; while( true ) { i++; try { myDepot.putContent(i); } catch( InterruptedException ex ) {} } Erzeugen der Daten Übergeben ans Depot
Consumer class Consumer extends Thread { private Depot myDepot; Consumer( Depot dep ) { myDepot = dep; } public void run() { while( true ) { try { int i = myDepot.getContent(); } catch (InterruptedException ex) {} System.out.println(i); } } } Holen der Daten Verarbeiten der Daten
Zusammenstöpseln package vs99.ex1; // hier die vorherigen Klassendefinitionen class ThreadDemo { public static void main(String args[]) { // Konfiguration des Systems Depot dep = new Depot(); Producer prod1 = new Producer(dep); Consumer con1 = new Consumer(dep); // Starten des Systems con1.start(); prod1.start(); } }