Voorbeeld van Java Thread

Welkom bij het Java Thread Voorbeeld. Proces en Draad zijn twee basisuitvoeringseenheden. Concurrency-programmering is meer gericht op Java-threads.

Proces

A process is a self contained execution environment and it can be seen as a program or application. However a program itself contains multiple processes inside it. Java runtime environment runs as a single process which contains different classes and programs as processes.

Draad

Een draad kan worden aangeduid als een lichtgewicht proces. Een draad heeft minder middelen nodig om te worden gemaakt en bestaat in het proces, de draad deelt de procesmiddelen.

Java Thread Voorbeeld

Elke Java-toepassing heeft minstens één thread – de hoofdthread. Hoewel er veel andere Java-threads op de achtergrond draaien, zoals geheugenbeheer, systeembeheer, signaalverwerking, enzovoort. Maar vanuit het oogpunt van de toepassing is de hoofdthread de eerste Java-thread en kunnen we er meerdere threads van maken. Multithreading verwijst naar twee of meer threads die gelijktijdig worden uitgevoerd in een enkel programma. Een computer met een single-core processor kan slechts één thread tegelijk uitvoeren en tijdsverdeling is de OS-functie om processortijd te delen tussen verschillende processen en threads.

Voordelen van Java Threads

  1. Java Threads zijn lichtgewicht in vergelijking met processen, het kost minder tijd en middelen om een thread te maken.
  2. Threads delen hun gegevens en code met hun ouderproces
  3. Contextwisseling tussen threads is meestal minder duur dan tussen processen.
  4. Thread-intercommunicatie is relatief eenvoudig dan procescommunicatie.

Java biedt twee manieren om programmatisch een thread te maken.

  1. Door de interface java.lang.Runnable te implementeren.
  2. Door de klasse java.lang.Thread uit te breiden.

Java Thread Voorbeeld – implementeren van Runnable interface

Om een klasse uitvoerbaar te maken, kunnen we de java.lang.Runnable interface implementeren en implementatie bieden in de public void run()-methode. Om deze klasse als Thread te gebruiken, moeten we een Thread-object maken door een object van deze Runnable-klasse door te geven en vervolgens de start()-methode aanroepen om de run()-methode in een aparte thread uit te voeren. Hier is een java-threadvoorbeeld door de Runnable-interface te implementeren.

package com.journaldev.threads;

public class HeavyWorkRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println("Doing heavy processing - START "+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
            // Verbinding maken met database, ongebruikte gegevens uit DB verwijderen
            doDBProcessing();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Doing heavy processing - END "+Thread.currentThread().getName());
    }

    private void doDBProcessing() throws InterruptedException {
        Thread.sleep(5000);
    }

}

Java Thread Voorbeeld – Threadklasse uitbreiden

We kunnen de java.lang.Thread-klasse uitbreiden om onze eigen java-threadklasse te maken en de run()-methode te overschrijven. Vervolgens kunnen we zijn object maken en de start()-methode aanroepen om onze aangepaste java-threadklasse uit te voeren. Hier is een eenvoudig java-threadvoorbeeld dat laat zien hoe je de Thread-klasse kunt uitbreiden.

package com.journaldev.threads;

public class MyThread extends Thread {

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        System.out.println("MyThread - START "+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
            // Verbinding maken met database, ongebruikte gegevens uit DB verwijderen
            doDBProcessing();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("MyThread - END "+Thread.currentThread().getName());
    }

    private void doDBProcessing() throws InterruptedException {
        Thread.sleep(5000);
    }
    
}

Hier is een testprogramma dat laat zien hoe je een java-thread kunt maken en uitvoeren.

package com.journaldev.threads;

public class ThreadRunExample {

    public static void main(String[] args){
        Thread t1 = new Thread(new HeavyWorkRunnable(), "t1");
        Thread t2 = new Thread(new HeavyWorkRunnable(), "t2");
        System.out.println("Starting Runnable threads");
        t1.start();
        t2.start();
        System.out.println("Runnable Threads has been started");
        Thread t3 = new MyThread("t3");
        Thread t4 = new MyThread("t4");
        System.out.println("Starting MyThreads");
        t3.start();
        t4.start();
        System.out.println("MyThreads has been started");
        
    }
}

Het resultaat van het bovenstaande java-threadvoorbeeldprogramma is:

Starting Runnable threads
Runnable Threads has been started
Doing heavy processing - START t1
Doing heavy processing - START t2
Starting MyThreads
MyThread - START Thread-0
MyThreads has been started
MyThread - START Thread-1
Doing heavy processing - END t2
MyThread - END Thread-1
MyThread - END Thread-0
Doing heavy processing - END t1

Eenmaal we een draad starten, hangt de uitvoering af van de OS-implementatie van timeslicing en kunnen we hun uitvoering niet controleren. We kunnen echter wel de prioriteit van draden instellen, maar zelfs dan garandeert het niet dat de draad met hogere prioriteit als eerste wordt uitgevoerd. Voer het bovenstaande programma meerdere keren uit en je zult zien dat er geen patroon is voor het starten en beëindigen van draden.

Runnable versus Thread

Als je klasse meer functionaliteit biedt dan alleen het uitvoeren als een draad, moet je de Runnable-interface implementeren om een manier te bieden om het als een draad uit te voeren. Als het enige doel van je klasse is om als draad te worden uitgevoerd, kun je de Thread-klasse uitbreiden. Het implementeren van Runnable heeft de voorkeur omdat Java het implementeren van meerdere interfaces ondersteunt. Als je de Thread-klasse uitbreidt, kun je geen andere klassen uitbreiden. Tip: Zoals je hebt opgemerkt, retourneert een draad geen waarde, maar wat als we willen dat onze draad wat verwerking doet en vervolgens het resultaat retourneert aan ons clientprogramma, bekijk dan onze Java Callable Future. Update: Vanaf Java 8 is Runnable een functionele interface en kunnen we lambda-uitdrukkingen gebruiken om de implementatie te geven in plaats van anonieme klassen te gebruiken. Voor meer details, bekijk Java 8 Functionele Interfaces.

Source:
https://www.digitalocean.com/community/tutorials/java-thread-example