Java Multithreading Uitgelegd: Concepten, Levenscyclus en Praktische Codevoorbeelden
Java applicaties moeten vaak meerdere taken simultaan uitvoeren. Deze tutorial begeleidt je door single-threaded versus multi-threaded uitvoering, de levenscyclus van een thread, synchronisatietechnieken, en hands-on codevoorbeelden die elk concept illustreren.
Wat Is Een Single Thread?
Een single thread in Java is de kleinste uitvoeringseenheid. De Java runtime creëert een user thread wanneer de applicatie start, en je kunt extra user of daemon threads toevoegen zoals nodig. Daemon threads draaien op de achtergrond en voorkomen niet dat de JVM afsluit.
Voorbeeld van een single thread:
package demotest;
public class GuruThread {
public static void main(String[] args) {
System.out.println("Single Thread");
}
}
Voordelen van single-threaded uitvoering:
- Minimale overhead – slechts één uitvoeringscontext wordt bijgehouden.
- Vereenvoudigde debugging en onderhoud.
Wat Is Multithreading in Java?
Multithreading stelt twee of meer threads in staat om concurrent te draaien, wat CPU-gebruik maximaliseert. Threads delen dezelfde geheugenruimte, dus context switches zijn snel en geheugengebruik blijft laag.
Voorbeeld van het aanmaken van twee gelijktijdige threads:
package demotest;
public class GuruThread1 implements Runnable {
public static void main(String[] args) {
Thread guruThread1 = new Thread("Guru1");
Thread guruThread2 = new Thread("Guru2");
guruThread1.start();
guruThread2.start();
System.out.println("Thread namen zijn als volgt:");
System.out.println(guruThread1.getName());
System.out.println(guruThread2.getName());
}
@Override
public void run() {
// Thread logica komt hier
}
}
Voordelen van multithreading:
- Non-blokkerende UI en achtergrondverwerking.
- Weerbaarheid – een exception in één thread stopt de anderen niet.
Thread Levenscyclus in Java
De thread levenscyclus bestaat uit vijf verschillende staten:
- New – Thread is geïnstantieerd maar nog niet gestart.
- Runnable – Thread is gestart en klaar voor uitvoering.
- Running – Thread is actief aan het uitvoeren.
- Waiting – Thread is opgeschort tot een specifieke gebeurtenis plaatsvindt.
- Dead – Thread heeft uitvoering voltooid.
Belangrijke Thread Methodes
| Methode | Beschrijving |
|---|---|
| start() | Start thread uitvoering; JVM roept run() aan. |
| sleep(long milliseconden) | Pauzeert de huidige thread voor de gespecificeerde duur. |
| getName() | Retourneert de thread naam. |
| setPriority(int newPriority) | Past thread prioriteit aan (1-10). |
| yield() | Suggereert de scheduler de huidige thread te pauzeren. |
Praktisch Thread Voorbeeld
Hieronder is een beknopt voorbeeld dat thread aanmaak, prioriteitsaanpassing en slapen demonstreert.
package demotest;
public class ThreadExample1 implements Runnable {
@Override
public void run() {
// Thread werk hier
}
public static void main(String[] args) {
Thread guruThread1 = new Thread();
guruThread1.start();
try {
Thread.sleep(1000); // pauzeer 1 seconde
} catch (InterruptedException e) {
e.printStackTrace();
}
guruThread1.setPriority(1);
System.out.println(guruThread1.getPriority());
System.out.println("Thread Draait");
}
}
Output voorbeeld:
Thread Synchronisatie
Wanneer meerdere threads gedeelde bronnen benaderen, zorgt synchronisatie voor dataconsistentie. In Java kun je kritieke secties wrappen met het synchronized sleutelwoord, wat exclusieve toegang garandeert.
synchronized(object) {
// gesynchroniseerd blok
}
Geavanceerd Multithreading Voorbeeld
Hieronder is een uitgebreider voorbeeld dat twee threads aanmaakt, elk de naam en een teller print met een seconde vertraging.
package demotest;
public class GuruThread2 {
public static void main(String[] args) {
GuruThread3 threadGuru1 = new GuruThread3("guru1");
threadGuru1.start();
GuruThread3 threadGuru2 = new GuruThread3("guru2");
threadGuru2.start();
}
}
class GuruThread3 implements Runnable {
private Thread guruthread;
private String guruname;
GuruThread3(String name) {
this.guruname = name;
}
@Override
public void run() {
System.out.println("Thread draait " + guruname);
for (int i = 0; i < 4; i++) {
System.out.println(i);
System.out.println(guruname);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread is onderbroken");
}
}
}
public void start() {
System.out.println("Thread gestart");
if (guruthread == null) {
guruthread = new Thread(this, guruname);
guruthread.start();
}
}
}
Typische output (geïllustreerd in de bijbehorende afbeelding):
Conclusie
- Multithreading bevrijdt de applicatie van blokkerende aanroepen en stelt gelijktijdige operaties in staat.
- De thread levenscyclus – New, Runnable, Running, Waiting, Dead – definieert de staten die een thread doorloopt.
- Synchronisatie is essentieel wanneer threads data delen, om race conditions te voorkomen.
- Praktische codevoorbeelden versterken begrip van thread aanmaak, levenscyclusbeheer en synchronisatie.
Java
- C++ Functies Uitgelegd met Praktische Codevoorbeelden
- C# Collections Beheersen: Een Praktische Tutorial met Real-World Voorbeelden
- C++ Multithreading beheersen: Efficiënt gelijktijdig programmeren
- Java Hello World: je eerste programma
- Java String.indexOf() beheersen: Substrings lokaliseren & praktische voorbeelden
- Java String.charAt() begrijpen: Syntaxis, Retourtype, Exceptions en Praktisch Voorbeeld
- Java's String compareTo() Methode beheersen: Syntaxis, Use Cases en Praktische Voorbeelden
- Constructor Overloading in Java – Uitgelegd met Praktische Codevoorbeelden
- Java-programma om te bepalen of een getal priem is
- Insertion Sort algoritme in Java: Duidelijk voorbeeld & stapsgewijze handleiding
- Selection Sort in Java: Stapsgewijze voorbeeld & complete code