Thread Management in Java
- Begriffsklärung
- Grundlegende Thread-Programmierung
- Weiterführende Konzepte
Gliederung
Begriffsklärung
Nebenläufig vs. Parallel
-
Prozess
- Programminstanz mit eigenem Speicherbereich
- Enthält immer >= 1 Thread
-
Thread
- leichtgewichtiger Prozess
Nebenläufig vs. Parallel
nebenläufig
parallel
unabhängig
unabhängig
& gleichzeitig
Vorgänge
sind
{
Nebenläufig vs. Parallel
nur nebenläufig
auch parallel
verteilt
Grundlegende Thread-Programmierung
static class RunnableThread implements Runnable {
@Override
public void run() {
// Thread-Logik
}
}
Thread runnableThread = new Thread(new RunnableThread());
Erzeugen und Ausführen
static class ExtendedThread extends Thread {
@Override
public void run() {
// Thread-Logik
}
}
Thread extendedThread = new ExtendedThread();
try {
Thread.sleep(1000);
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// ...
}
Pausieren
= Warten ohne Verschwendung von Prozessorressourcen
public static void main(String[] args)
throws InterruptedException {
Thread t = new Thread(() -> {
// irgendeine Berechnung
});
t.start();
t.join(1000);
}
Auf anderen Thread warten
Thread t = new Thread(() -> {
// Endlose Schleife bis zum Unterbrechen.
while (true) {
if (Thread.interrupted()) {
return;
}
}
});
t.start();
t.interrupt();
System.out.println("Unterbrechungsindikator ist"
+ (t.isInterrupted() ? "" : " nicht")
+ " gesetzt.");
Unterbrechen
interrupt()
isInterrupted()
!
?
interrupted()
Weiterführende Konzepte
- ID
- Name
- Priorität
- Status
1 <= x <= 10
Eigenschaften
von Thread-Objekten
Eigenschaften
von Thread-Objekten
Status
NEW
RUNNABLE
TERMINATED
WAITING
TIMED_WAITING
start()
interrupt()
join(n)
join()
Eigenschaften
von Thread-Objekten
Thread t = new Thread(() -> {});
System.out.printf("Id: %s\nName: %s\nPrioritaet: %s\nStatus: %s\n\n",
t.getId(), t.getName(), t.getPriority(), t.getState());
t.setName("Calculator");
t.setPriority(1);
t.start();
System.out.printf("Name: %s\nPrioritaet: %s\nStatus: %s\n\n",
t.getName(), t.getPriority(), t.getState());
t.interrupt();
t.join();
System.out.printf("Status: %s\n\n", t.getState());
Thread t = new Thread(() -> {});
System.out.printf(...
t.setName("Calculator");
t.setPriority(1);
t.start();
System.out.printf(...
t.interrupt();
t.join();
System.out.printf(...
Eigenschaften
von Thread-Objekten
Id: 11 Name: Thread-0 Prioritaet: 5 Status: NEW Name: Calculator Prioritaet: 1 Status: RUNNABLE Status: TERMINATED
Ausgabe
Daemon-Threads
public static void main(String[] args) {
Thread dt = new Thread(() -> {
while (true) {}
});
dt.setDaemon(true);
dt.start();
}
Daemon-Threads
public static void main(String[] args) {
Thread dt = new Thread(() -> {
while (true) {}
});
dt.setDaemon(true);
dt.start();
// Dieses Programm endet hier
// trotz der Endlosschleife im Daemon-Thread.
}
Thread-Gruppen
ThreadGroup parentGroup = new ThreadGroup("Parent");
new ThreadGroup(parentGroup, "Child");
new Thread(parentGroup, () -> {});
Thread-Factories
ThreadFactory threadFactory = r -> null;
Thread t = threadFactory.newThread(() -> {});
if (t == null) {
System.out.println("Thread ist null.");
}
Thread-Factories
ThreadFactory threadFactory = r -> null;
Thread t = threadFactory.newThread(() -> {});
if (t == null) {
System.out.println("Thread ist null.");
}
// Gibt "Thread ist null." aus.
Ausnahmebehandlung
static class UncaughtExceptionHandler
implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.printf("Look! A %s!\n", e);
}
}
Ausnahmebehandlung
static class ExceptionThread implements Runnable {
@Override
public void run() {
try {
throw new InterruptedException();
} catch (InterruptedException e) {
throw new NumberFormatException();
}
}
}
public static void main(String[] args) {
Thread exceptionT = new Thread(new ExceptionThread());
exceptionT.setUncaughtExceptionHandler(
new UncaughtExceptionHandler());
exceptionT.start();
}
Ausnahmebehandlung
static class ExceptionThread implements Runnable {
@Override
public void run() {
try {
throw new InterruptedException();
} catch (InterruptedException e) {
throw new NumberFormatException();
}
}
}
public static void main(String[] args) {
Thread exceptionT = new Thread(new ExceptionThread());
exceptionT.setUncaughtExceptionHandler(
new UncaughtExceptionHandler());
exceptionT.start();
// Gibt "Look! A java.lang.NumberFormatException!" aus.
}
Datenlokalität
static class LocalDataRunnable implements Runnable {
Date dateShared = new Date();
@Override
public void run() {
System.out.printf("[dateShared] %s\n", dateShared);
}
}
Datenlokalität
static class LocalDataRunnable implements Runnable {
private static ThreadLocal<Date> dateLocal
= ThreadLocal.withInitial(Date::new);
Date dateShared = new Date();
@Override
public void run() {
System.out.printf("[dateLocal] %s\n", dateLocal.get());
System.out.printf("[dateShared] %s\n", dateShared);
}
}
Datenlokalität
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new LocalDataRunnable()),
t2 = new Thread(new LocalDataRunnable());
t1.start();
t1.join();
TimeUnit.SECONDS.sleep(2);
t2.start();
t2.join();
}
[dateLocal] Fri Nov 01 20:00:00 CET 2019 [dateShared] Fri Nov 01 20:00:00 CET 2019 [dateLocal] Fri Nov 01 20:00:02 CET 2019 [dateShared] Fri Nov 01 20:00:00 CET 2019
Ausgabe
Zusammenfassung
Thread Management in Java
By Jonas Thelemann
Thread Management in Java
- 63