Threads Richard Göbel
Threads - Einführung Ein Thread ermöglicht die quasi-parallele Bearbeitung unterschiedlicher Aufgaben. Threads laufen im Unterschied zu Prozessen im gleichen virtuellen Speicher ab: Threads lassen sich effizienter starten Gemeinsamer Zugriff auf globale Objekte möglich Fehler in einem Thread können sich auch auf andere Threads auswirken
Threads - Anwendungsbeispiele Grafische Benutzeroberfläche Bearbeitung einer größeren Aufgabenstellung starten Integration von Animationen Netzwerkprogrammierung Server bedient unterschiedliche Clients gleichzeitig Client kommuniziert asynchron mit dem Server und vieles andere mehr
Optionen zur Erzeugung eines Threads Definition einer Unterklasse der Klasse Thread Bereitstellung der Methode void run() mit dem Rumpf des Threads Thread kann mit Methode void start() gestartet werden Thread wartet mit Methode void sleep(int msek) Thread soll selbständig die Arbeit beenden (z. B. als Ergebnis eines externen Signals) Implementierung des Interface Runnable Bereitstellung der Methode void run() Erzeugung eines Threads mit dem Konstruktor Thread(Runnable target)
Programmbeispiel - News Ticker Teil 1 JLabel display = new JLabel(); boolean tickerRunning = false; class NewsTicker extends Thread { private String news = ". . ."; private int l = 16; public void run() { int s; while (tickerRunning) { for (int i = -l; i <= news.length()-l; i++) { if (i < 0) s = 0; else s = i; display.setText(news.substring(s,i+l)); try{sleep(200);} catch (InterruptedException e) {return;}}}}}
Programmbeispiel - News Ticker Teil 2 Thread starten Thread ticker = new NewsTicker(); tickerRunning = true; ticker.start(); Thread anhalten tickerRunning = false;
Zustand eines Threads Thread wurde erzeugt aber noch nicht gestartet Thread wurde gestartet und läuft (runnable) Thread wurde gestartet und wartet (not runnable) Methode „run“ des Thread wurde beendet (dead)
Implementierung des Interface Runnable durch eine beliebige Klasse: class MyClass implements Runnable { . . . public void run() { } Starten des Thread MyClass c = new MyClass( . . . ); Thread aThread = new Thread(c); aThread.start();
Problem: Synchronisation von Threads Puffer für Zeichenkette Thread A Thread B schreibt Dies ist liest Dies ist schreibt Dies ist ein Test
Synchronisation mit einem Monitor - Optionen Deklaration einer Methode mit dem Schlüsselwort synchronized Deklaration eines Blocks mit dem Konstrukt synchronized ( expression ) block Die so markierten Anweisungen dürfen nicht gleichzeitig : auf das zugehörige Objekt für die Methode oder auf das Ergebnisobjekt des Ausdrucks angewendet werden Der interne Scheduler blockiert bei Bedarf die Ausführung von Anweisungen für ein Objekt
Verwendung des Konstrukts „synchronized“ Thread A StringBuffer b Thread B synchronized (b) { . . . b.append( . . . ) b.append( . . .) } String s; . . . synchronized (b) { s = new String(b); }
Manuelle Synchronisierung Thread A Object o Thread B synchronized (o) { . . . o.notify() } . . . synchronized (o) { o.wait(); }
Probleme bei der Verwendung eines Monitors Deadlock (Verklemmung): Threads greifen wechselweise auf benötigte Ressourcen zu. Starvation: Ein Thread wird aufgrund der Arbeitsweise anderer Threads nie aufgerufen. Lösung: Realisierung einer Kommunikationsstruktur, die aus den Rahmenbedingungen der Anwendung diese Probleme ausschließt