Heim  >  Artikel  >  Java  >  Ein praktischer Leitfaden zum JAVA Core Concurrency Programming Model

Ein praktischer Leitfaden zum JAVA Core Concurrency Programming Model

PHPz
PHPzOriginal
2023-11-08 16:45:211310Durchsuche

Ein praktischer Leitfaden zum JAVA Core Concurrency Programming Model

Praktischer Leitfaden zum JAVA Core Concurrency Programming Model

Im heutigen Bereich der Softwareentwicklung sind Multi-Core-Prozessoren und verteilte Systeme zum Mainstream geworden. Um die Hardwareressourcen voll auszunutzen, müssen wir gleichzeitige Programme schreiben, um eine parallele Verarbeitung zu erreichen und die Leistung zu verbessern. Als gängige Programmiersprache bietet JAVA eine große Auswahl an Modellen und Werkzeugen für die gleichzeitige Programmierung. In diesem Artikel erhalten Sie anhand einiger spezifischer Codebeispiele ein umfassendes Verständnis der wichtigsten Modelle der gleichzeitigen Programmierung von JAVA und lernen, wie Sie diese Modelle zum Üben der gleichzeitigen Programmierung verwenden.

  1. Threading-Grundlagen
    Werfen wir zunächst einen Blick auf das grundlegendste Element der gleichzeitigen Programmierung in JAVA: Threads. Threads in JAVA werden durch die Klasse java.lang.Thread dargestellt. Das Folgende ist ein einfaches Thread-Beispiel:
public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("Hello, this is my thread!");
    }

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
    }
}

In diesem Beispiel erstellen wir eine benutzerdefinierte Thread-Klasse MyThread, die von Thread erbt, und schreiben die run-Methode neu, um eine einfache Nachricht in der run-Methode auszugeben. In der Hauptmethode erstellen wir eine Instanz von MyThread und starten den Thread über die Startmethode.

  1. Runnable-Schnittstelle
    Zusätzlich zum Erben der Thread-Klasse können wir auch die java.lang.Runnable-Schnittstelle implementieren, um Threads zu erstellen. Das Folgende ist ein Beispiel für die Verwendung der Runnable-Schnittstelle:
public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Hello, this is my runnable!");
    }

    public static void main(String[] args) {
        Thread myThread = new Thread(new MyRunnable());
        myThread.start();
    }
}

In diesem Beispiel haben wir eine benutzerdefinierte Klasse MyRunnable erstellt, die die Runnable-Schnittstelle implementiert, und die Ausführungsmethode überschrieben. In der Hauptmethode erstellen wir ein Thread-Objekt, übergeben die Instanz von MyRunnable als Parameter und starten den Thread über die Startmethode.

  1. Thread-Pool
    Bei der tatsächlichen gleichzeitigen Programmierung führt das häufige Erstellen und Zerstören von Threads zu einem großen Leistungsaufwand. Daher stellt JAVA einen Thread-Pool zur Verwaltung und Wiederverwendung von Threads bereit. Hier ist ein einfaches Beispiel für die Verwendung eines Thread-Pools:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 5; i++) {
            Runnable worker = new WorkerThread("" + i);
            executor.execute(worker);
        }
        executor.shutdown();
        while (!executor.isTerminated()) {
        }
        System.out.println("Finished all threads");
    }
}

class WorkerThread implements Runnable {
    private String message;

    public WorkerThread(String s) {
        this.message = s;
    }

    public void run() {
        System.out.println(Thread.currentThread().getName() + " (Start) message = " + message);
        processMessage();
        System.out.println(Thread.currentThread().getName() + " (End)");
    }

    private void processMessage() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

In diesem Beispiel verwenden wir die Dienstprogrammklasse Executors, um einen Thread-Pool mit einer festen Größe von 3 zu erstellen. Anschließend haben wir 5 Instanzen von WorkerThread erstellt und an den Thread-Pool übermittelt. Der Thread-Pool ist für die Verwaltung der Ausführung dieser Threads verantwortlich.

  1. Sperren und Synchronisation
    Bei der gleichzeitigen Programmierung sind Sperren und Synchronisation sehr wichtige Konzepte. JAVA stellt das synchronisierte Schlüsselwort und die Lock-Schnittstelle bereit, um uns bei der Synchronisierung zwischen Threads zu helfen. Das Folgende ist ein Beispiel für die Verwendung des synchronisierten Schlüsselworts:
public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized void decrement() {
        count--;
    }

    public synchronized int getCount() {
        return count;
    }
}

In diesem Beispiel haben wir eine Counter-Klasse erstellt, in der die Methoden inkrementieren, dekrementieren und getCount alle das synchronisierte Schlüsselwort verwenden, um eine Synchronisierung zu erreichen. Dadurch wird sichergestellt, dass Aufrufe dieser Methoden von mehreren Threads sicher sind.

Darüber hinaus bietet das Parallelitätspaket von JAVA auch mehrere Sperrimplementierungen, wie z. B. ReentrantLock und ReadWriteLock. Das Folgende ist ein Beispiel für die Verwendung von ReentrantLock:

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {
    private final ReentrantLock lock = new ReentrantLock();

    public void performTask() {
        lock.lock();
        try {
            // 执行需要同步的代码块
        } finally {
            lock.unlock();
        }
    }
}

In diesem Beispiel erstellen wir eine Instanz von ReentrantLock und verwenden Sperren und Entsperren, um den kritischen Abschnitt zu sperren und zu entsperren. Diese Methode ist flexibler als das synchronisierte Schlüsselwort und kann den Erwerb und die Freigabe von Sperren manuell steuern.

  1. Gleichzeitige Sammlungen
    Um Daten bei der gleichzeitigen Programmierung sicher auszutauschen, stellt JAVA einige nebenläufigkeitssichere Sammlungsklassen bereit, wie z. B. ConcurrentHashMap und CopyOnWriteArrayList. Hier ist ein Beispiel für die Verwendung von ConcurrentHashMap:
import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentMapExample {
    private ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();

    public void addKeyValuePair(String key, String value) {
        map.put(key, value);
    }

    public String getValueByKey(String key) {
        return map.get(key);
    }
}

In diesem Beispiel erstellen wir eine ConcurrentHashMap-Instanz und verwenden die Put- und Get-Methoden, um die Daten in der Map sicher zu manipulieren, ohne dass zusätzliche Synchronisierungsvorgänge erforderlich sind.

Durch die obigen Beispiele verfügen wir über ein tiefgreifendes Verständnis des Kernmodells der gleichzeitigen Programmierung von JAVA, einschließlich Thread-Grundlagen, Thread-Pools, Sperren und Synchronisierung sowie gleichzeitiger Sammlungen. In tatsächlichen Projekten kann die sinnvolle Verwendung dieser gleichzeitigen Programmiermodelle die Programmleistung und -stabilität verbessern. Ich hoffe, dass dieser Artikel den Lesern helfen kann, die Kenntnisse der gleichzeitigen Programmierung in JAVA besser zu beherrschen und in der Praxis effiziente gleichzeitige Programme zu schreiben.

Das obige ist der detaillierte Inhalt vonEin praktischer Leitfaden zum JAVA Core Concurrency Programming Model. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn