Java/C++ F. Monninger Threading in Java Threading in Java und C++ Felix Monninger Institut für Informatik TU München Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen September 2009 1 / 37 Inhaltsverzeichnis Java/C++ F. Monninger Threading in Java Threading in Java Geschichtliches Threads in Java Basics Ressourcensynchronisation Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen Threading in C++0x Quellen 2 / 37 Geschichtliches Java/C++ F. Monninger Threading in Java Threading früher: I vom OS bereitgestellte C-libraries, die der Programmierer benutzen konnte I eingebauter Thread-Support in Ada, fast schon so wie heute in Java I kommerzielle Threading-Bibliotheken für Java Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen Ab J2SE 5.0 (2004) Threading-Klassen 3 / 37 Threads in Java Java/C++ F. Monninger Threading in Java I einzeln laufende Programmteile, die untereinander über Objekte kommunizieren I werden erzeugt, gestartet, manipulieren Daten, rufen Methoden auf, enden I sind Teile eines Prozesses und teilen sich dessen Adressraum I unabhängig von Hardwaregegebenheiten (Anzahl der Prozessoren etc.) I Threads in Java bilden eine virtuelle shared-memory Architektur Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen 4 / 37 Warum Threading in Java? Java/C++ F. Monninger I ürsprünglich zur Aufteilung des Programms in ’Sinneinheiten’ I um Reaktionszeiten des Programms zu verkleinern (z.B. GUI) I bessere Nutzung paralleler Hardware (Multiprozessor-Architekturen) I I Nonblocking I/O Timer I I I Threading in Java Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen früher ein eigener Thread, der sleep()t und dann benachrichtigt heute genau dasselbe objektorientiert in einer Klasse gekapselt unabhängige Tasks (z.B. Webserver, Server für wissenschaftliche Berechnungen) ⇒ Threading sehr wichtig in komplexeren Java-Programmen 5 / 37 Grenzen des Threadings Java/C++ F. Monninger Threading in Java Mögliche Argumente gegen den Einsatz von Threads: I Nichtdeterminismus → ganz neue Programmfehler werden möglich I Zusatzaufwand zur Eingrenzung der höheren Fehleranfälligkeit wird notwendig I Performance-Overhead durch Thread-Scheduling, Synchronisation und Context-Switching Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen ⇒ Manchmal ist es sogar sinnvoll, einen Programmteil nicht als Thread zu realisieren, sondern in einen eigenen Prozess auszulagern 6 / 37 Erzeugen eines Threads Java/C++ F. Monninger Möglichkeiten zum Erzeugen eines Threads: I Implementieren von ’Runnable’ 1 2 3 4 5 public class MeinThread implements Runnable { public void run () { // A n w e i s u n g e n } } I Erben von ’Thread’ 1 2 3 4 5 6 7 8 public class MeinThread2 extends Thread { public MeinThread2 () { super ( " MeinThread2 " ); } public void run () { // A n w e i s u n g e n } } Threading in Java Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen ⇒ Implementieren von Runnable bevorzugt 7 / 37 Starten des Threads Java/C++ F. Monninger Threading in Java I start() iniziiert die Threadausführung und ruft run() auf I run() enthält den vom Thread auszuführenden Code Genauer: Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen Runnable Erzeugen und Starten einer Instanz per new Thread(MeinThread).start() Thread Starten einer Instanz per meinThread2Instanz.start() 8 / 37 Joinen von Threads Java/C++ F. Monninger Threading in Java 1 2 3 4 5 6 7 8 I Thread.join() wartet, bis der Thread stoppt. I Thread.join(long l) wartet maximal l Millisekunden, bis der Thread stoppt main () { ... t1 . start (); t2 . start (); Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen t1 . join (); t2 . join (); } 9 / 37 stop(), resume() & suspend() Java/C++ F. Monninger Threading in Java I Methoden zum starten, stoppen und pausieren eines Threads I inzwischen als deprecated (veraltet, überholt) markiert Beeinflussung von außen ist gefährlich! I Dateninkonsistenz I Kritische Abschnitte können verlassen werden, ohne Lock zu entsperren → Deadlocks Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen ⇒ nur der Thread selbst kann entscheiden, wann er bereit ist, sich zu beenden oder CPU-Zeit an einen anderen Thread abzugeben 10 / 37 Sonstige Methoden Java/C++ F. Monninger Threading in Java Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings I sleep(long l): einen Thread für l ms anhalten I isAlive(): testet, ob der Thread noch nicht beendet ist Threading in C++0x Quellen 11 / 37 Zusatzaufwand durch Threading Java/C++ F. Monninger Threading in Java Fehlende Synchronisation der Daten führt schnell zu Fehlverhalten Daher: viele verschiedene Strategien und Datenstrukturen zur Synchronisation des Threadzugriffs auf Daten Beispiele von Fehlsituationen: I Race Conditions I Deadlocks Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen 12 / 37 Race Conditions - ’Wettlaufsituationen’ Java/C++ F. Monninger Threading in Java I ’Konstellation, in denen das Ergebnis einer Operation vom zeitlichen Verhalten bestimmter Einzeloperationen abhängt.’ Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen I haben oft schwer auffindbare Programmfehler zur Folge Eclipse-Beispiel einer Race Condition 13 / 37 Deadlocks - ’Verklemmungen’ Java/C++ F. Monninger Definition: ’Eine Menge von Prozessen befindet sich in einem Deadlock, wenn jeder dieser Prozesse auf ein Ereignis wartet, das nur ein anderer Prozess aus dieser Menge verursachen kann.’ 4 notwendige Kriterien für das Auftreten eines Deadlocks (Coffman et al.): No Preemption: Nur die Prozesse selbst geben Betriebsmittel (Standardbeispiel: Drucker) wieder frei (keine kontrollierende Instanz) Threading in Java Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen Hold and Wait: Anforderung von neuen Betriebsmitteln bei Beibehaltung des Zugriffs auf alte Betriebsmittel Mutual Exclusion: Exklusiver Zugriff auf Betriebsmittel Circular Wait: Zirkuläre Abhängigkeiten: zwei oder mehrere Prozesse warten auf die Freigabe eines Betriebsmittels, das jeweils dem nächsten Prozess der Kette gehört Livelock: ’lebende Verklemmung’ 14 / 37 Verklemmungsverhinderung - ’deadlock prevention’ Java/C++ F. Monninger Threading in Java Prävention von Deadlocks liegt vor, wenn eine der 4 notwendigen Bedingungen nicht erfüllt wird: Preemption: Entziehung von Betriebsmitteln und Zuteilung an einen anderen Prozess Hold and Wait vorbeugen: Zuteilung der benötigten Betriebsmittel erst, wenn alle verfügbar sind Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen Mutual Exclusion beseitigen: Exklusiven Zugriff beseitigen, z.B. Spooling bei Drucker Circular Wait verhindern: Betriebsmittel werden durchnummeriert und in (aufsteigender) Reihenfolge vergeben 15 / 37 Verklemmungsvermeidung - ’deadlock avoidance’ Java/C++ F. Monninger Threading in Java I Das System versucht, die Prozesse derart zu überwachen, dass sie nicht verklemmen. I ’Sicherer Zustand’: Zustand, in dem es eine Reihenfolge der Betriebsmittelzuteilung gibt, die zu korrektem Ablauf führt I Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen Alle möglichen weiteren Programmablufe müssen bekannt sein ⇒ Kompliziert und häufig aufwändig 16 / 37 Verklemmungsbeseitigung - ’recovery from deadlock’ Java/C++ F. Monninger Threading in Java Beseitigung durch Prozessabbruch Gezielte Beendung von beteiligten Prozessen. Schlecht automatisierbar. Beseitigung durch Preemption Pausierung eines beteiligten Prozesses und temporäre Neuverteilung seiner Betriebsmittel. In der Praxis schwer realisierbar. Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen Beseitigung durch Rollback Sicherungspunkte des Prozesses, zu denen bei Bedarf zurückgesprungen werden kann. In manchen Situationen ungeeignet (z.B. CD-Brennvorgang) 17 / 37 Data sharing Java/C++ F. Monninger Threading in Java Komplexität entsteht, sobald mehrere Threads Daten gemeinsam benutzen → Race Conditions, Deadlocks Kritische Abschnitte (:= Abschnitte, die shared-data enthalten) werden behandelt mit einem Mutex – mutually exclusive lock Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen 18 / 37 Semaphore 1 Java/C++ F. Monninger Variable zur Realisierung eines Mutex ”Das Wort Semaphor geht auf die Formsignale, mechanische Eisenbahnsignale zurück. Die dort verwendeten Semaphore zeigen an, ob ein Zug einen Gleisabschnitt befahren darf oder ob nicht.” Threading in Java 1 2 3 4 struct Semaphor { int zaehler ; Queue queue ; } Threading in C++0x I zaehler gibt an, wie viele Betriebsmittel zur Verfügung stehen besitzt zwei Operationen, P() – ’passieren’ für das Betreten und V() – ’freigeben’ beim Verlassen eines kritischen Abschnittes P() hält an, solange der Wert von zaehler = 0 ist V() erhöht den Wert von zaehler um 1 I I I I I I Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Quellen 19 / 37 Semaphore 2 Java/C++ F. Monninger Threading in Java I falls zaehler zu Beginn 1, binäres Semaphor (häufigst verwendetes Semaphor.) I starkes Semaphor: wartende Prozesse werden in Reihenfolge (Queue) wieder aktiviert; schwaches Semaphor: keine Festlegung der Aktivierungsreihenfolge I Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen P() und V() müssen atomare Operationen sein (⇒ test-and-set-Hardwareinstruktion) 20 / 37 Monitore und synchronized Java/C++ F. Monninger Threading in Java in Java besitzt jedes Object ein Mutex in Form eines Monitors I ’Monitor’: Modul (Datentyp, Klasse), auf das nur ein Thread auf einmal zugreifen kann I Monitor kümmert sich selbst um die entsprechende Synchronisation I jedes Java ’Object’ besitzt Monitoreigenschaften, bei Verwendung von synchronized wird der jeweilige Monitor gelockt Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen 21 / 37 Monitore und synchronized Java/C++ F. Monninger Threading in Java 1 2 3 4 5 6 7 8 9 10 1 2 3 4 class A { private SomeType data ; synchronized public void fct1 (...) { ... } synchronized public void fct2 (...) { ... } Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen } synchronized ( obj ) { // Anweisungen , die erst ablaufen , wenn das Lock // auf ’ obj ’ erworben wurde } 22 / 37 wait(), notify() und notifyAll() Java/C++ F. Monninger Threading in Java Interprozess(-thread)kommunikation innerhalb eines Monitors: Threads warten auf Bedingungen, die ein anderer Thread schafft und sie anschließend benachrichtigt I wait() lässt den aktuellen Thread schlafen, bis ein anderer notify() aufruft I notify() lässt den ersten mit wait() angehaltenen Thread fortfahren I notifyAll() lässt alle wartenden Threads fortfahren Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen Eclipse-Beispiel 23 / 37 Das Keyword volatile Java/C++ F. Monninger I JVM cacht Variablen als lokale Kopie (z.B. in Prozessorregister) I → andere Threads sehen evtl. falschen Variablenwert I Optimierungen des (JIT-)Compilers können Verzögerungen beim Zurückschreiben in den Hauptspeicher zur Folge haben I → Java Spezifikation: Beim Betreten/Verlassen eines synchronized-Abschnitts darf es keine gecachten Variablen geben Threading in Java Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen volatile kennzeichnet eine von mehreren Threads benutzte Variable I Die Variable wird nie Thread-lokal gecached I ’verhält sich wie’ synchronized-block (synchronisiert auf sich selbst) um die Variable 24 / 37 Vergleich synchronized - volatile Java/C++ F. Monninger Threading in Java Eigenschaft Variablentyp synchronized Object Blockierend Gecachte Var. sync. Synchronisation Ja Ja Beim Betreten/ Verlassen eines synchronizedBlocks Ja Verschiedene Operationen zu einer elementaren kombinieren volatile Object oder primitive Nein Ja (Ab Java 5) Beim Variablenzugriff Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen Ja (Ab Java 5) 25 / 37 ThreadLocals Java/C++ F. Monninger Threading in Java I Klassenattribute, die für jeden Thread unabhängig neu instanziiert werden (jeder Thread hat einen eigenen Satz von Attributen) I stärkere Kapselung als ’private’, sozusagen ”thread-private” I typischerweise als static private deklariert Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen 26 / 37 User-Threads ↔ Daemon-Threads Java/C++ F. Monninger Threading in Java Neben den bisher betrachteten sog. User-Threads gibt es noch die Daemon-Threads. Eigenschaften: I Programm endet, sobald alle User-Threads beendet sind. I Daemon-Threads werden meist für Verwaltungsaufgaben verwendet, z.B. Garbage Collector I Ein Thread wird zum Deamon per setDaemon(true) nach Erzeugung Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen 27 / 37 Threadzustände Java/C++ F. Monninger Threading in Java Ein Thread ist eine ’Zustandsmaschine’ mit den Zuständen new, ready, running, inactive, finished Folgende Zustandsänderungen sind möglich: Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings I Nach der Erzeugung: new Threading in C++0x I Nach start(): ready, dann running Quellen I Beim Warten auf ein Lock oder suspend(): inactive I Nach Beendigung oder stop() Was passiert, nachdem ein Thread von mehreren seine Arbeit erledigt hat? 28 / 37 Scheduling Java/C++ F. Monninger Threading in Java Der Scheduler entscheidet, wem wieviel Prozessorzeit zugeteilt wird I I Jedem Thread ist eine Priorität zugeordnet (niedrigste 1 - 10 höchste) Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen Thread.yield() 29 / 37 Wie werden Threads von der VM realisiert? Java/C++ F. Monninger Threading in Java Zwei Möglichkeiten: I I das OS stellt Threading-Funktionen bereit (tun alle TM modernen Betriebssysteme) – nativer Thread früher & auf anderen Plattformen: VM implementiert Threads selbst – Green Thread Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen In Solaris werden native Threads ab JDK 1.2 (1998), in Linux ab ab JDK 1.3 (2000) unterstützt 30 / 37 Green Threads vs. Native Threads Java/C++ F. Monninger Threading in Java Vorteile Green Thread: I bessere Portierbarkeit der Java VM I Unabhängigkeit von den verschiedenen Threadingbibliotheken der Plattformen I Threads verhalten sich unter allen Plattformen ’gleich’ Nachteile Green Thread: I ist selbst dem Threading des Betriebssystems unterworfen, deshalb nur ein Prozessor benutzbar! ⇒ schlechte Skalierbarkeit I Green Threads in der Java VM laufen am Stück, Threads wechseln sich nicht alle x ms ab Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen 31 / 37 Green Threads vs. Native Threads Java/C++ F. Monninger Vorteile Nativer Thread: I Threads können ’echt parallel’ laufen I geringerer Verwaltungsaufwand (→ Programmieraufwand) für die Java VM I das Betriebssystem kann das Thread-Scheduling sogar selbst übernehmen Threading in Java Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen Benchmarks unter Linux ergaben: I Green Threads sind schneller bei der Erzeugung von Threads sowie der Ressourcensynchronisation I Native Threads (hier: Linux) sind sehr viel schneller bei I/O Operationen sowie Context Switching 32 / 37 Heutige Situation Java/C++ F. Monninger Fast auf allen Plattformen native Threads Unter anderem: Windows: Java-Threads laufen direkt als Windows-Threads im VM-Prozess (zu beobachten im Task Manager) Linux (ab JDK 1.3): Threads wurden als eigenständige Prozesse vom Hauptprozess abgespalten (’gecloned’), was damals unter Linux so üblich war. Die Threads waren eigene Prozesse, vom Linux-Prozessscheduler verwaltet. Erzeugung einer großen Anzahl an Threads war unter Linux bedeutend langsamer als z.B. unter Solaris oder Windows. Seit ca. 2002 gibt es in Linux ”richtige” Threads Threading in Java Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen 33 / 37 Threading in C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 Java/C++ F. Monninger Threading in Java Im Großen und Ganzen ähnlich zu Java-Threads, wie für C++ üblich jedoch stark mit Templates realisiert Simples Beispiel: # include < thread > # include < iostream > void my_thread_func () { std :: cout < < " hello " << std :: endl ; } Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen int main () { std :: thread t ( my_thread_fun c ); t . join (); } 34 / 37 Unterschiede zum Java-Threading Java/C++ F. Monninger I I 1 2 3 4 5 6 7 8 kein synchronized ähnliches Keyword, aber Klassen, deren Instanzen die gleiche Aufgabe übernehmen std::lock() zum Schließen mehrerer Locks gleichzeitig und zur Vermeidung von Deadlocks: ”All arguments are locked via a sequence of calls to lock(), try lock(), or unlock() on each argument. The sequence of calls shall not result in deadlock, but is otherwise unspecified.” ’try-and-back-off ’-Algorithmus. Kann bei schlechter Implementierung evtl. zu Livelock führen Threading in Java Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen std :: mutex m ; unsigned counter =0; unsigned increment () { std :: lock_guard < std :: mutex > lk ( m ); return ++ counter ; } 35 / 37 Quellen Java/C++ F. Monninger Threading in Java I S. Oaks, H. Wong: Java Threads (O’Reilly 2004) I http://www.dpunkt.de/java/Programmieren_mit_ Java/Multithreading/1.html I http://de.wikipedia.org (verschiedene) I http://www.go4expert.com/forums/showthread. php?t=4177 I Hans Boehm, Sarita Adve: ’Foundations of the C++ Concurrency Model’ I http://www.justsoftwaresolutions.co.uk/ threading/multithreading-in-c+ +0x-part-1-starting-threads.html Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen 36 / 37 Quellen Java/C++ F. Monninger Threading in Java I Java Api Documentation: http://java.sun.com/ j2se/1.4.2/docs/api/java/lang/Thread.html I wait, notify, notifyAll: http://www.java-samples. com/showtutorial.php?tutorialid=306 I Geschichtliches Threads in Java Basics Ressourcensynchronisati Sonstige Threadingmechanismen Das Java Threading-System Realisierung des Threadings Threading in C++0x Quellen volatile: http://www.javamex.com/tutorials/ synchronization_volatile.shtml 37 / 37