Begriffe #
Parallelität (Parallelism) hat zum Ziel, dass das Programm schneller fertig wird. Zum Beispiel kann ein Ablauf in mehrere Teilabläufe aufgeteilt werden, damit die Teile dann auf verschiedenen Prozessen laufen können.
Nebenläufigkeit (Concurrency) hat nicht unbedingt ein schnelleres Programm zum Ziel, sondern Abläufe verzahnt durchführen können. Beispielsweise können Abläufe gleichzeitig auf gemeinsame Ressourcen lesend zugreifen oder gesperrt werden, wenn einer schreiben muss.
Es gilt jedoch, dass immer mehrere Threads interagieren.
Themen #
Java bietet den Programmierern einige Möglichkeiten das Programm mit mehreren Threads zu optimieren. Zentral ist sicher die Monitor-Synchronisation sowie die spezifischen Synchronisationsprimitiven. Für die Parallelität sind dann auch die Thread Pools wichtig. Falls lock-frei gearbeitet werden soll, muss das Speichermodell mit dem “volatile” keyword und den Atomic-Klassen vom Programmierer gut gekannt werden.
Einführung #
Es gibt zwei verschiedene Betriebssystem-Komponenten, die unterschieden werden müssen. Das Erstere ist ein Prozess, der einen eigenen Adressraum hat. Letzteres ist der Thread, der innerhalb eines Prozesses läuft und den Adressraum mit anderen Threads teilt. Letzteres bedeutet, dass ein Thread auf Variablen und generell auf Ressourcen anderer Threads zugreifen kann.
Java ist ein Single Prozess System. Das heisst, dass die JVM (Java Virtual Machine) ein Prozess im Betriebssystem ist, der mehrere Threads haben kann.
Ein Thread muss nach dem Instanzieren gestartet werden. Das kann zum Beispiel so gemacht werden:
Thread myThread = new Thread() -> {
//Thread Code.
});
myThread.start();
Man kann dem Thread Konstruktor aber auch ein Runnable
übergeben oder sogar von der Thread Klasse erben.
Wichtig zu wissen ist, dass ein Thread erst mit der start()
Methode anfängt zu laufen. Ausserdem werden unbehandelte Exception von anderen Threads ignoriert. Der Thread ist beendet, wenn die run()
Methode durchlaufen ist.
Wenn mehrere Threads gestartet wurden, muss ziemlich sicher irgendwann auf ihre Beendigung gewartet werden. Das kann mit der join()
Methode gemacht werden. Wenn der Thread beendet werden soll, sobald das Programm beendet wird, kann der Thread als Daemon markiert werden. Diese werden beendet, wenn die main Funktion zurückkehrt.