Interrupt-Mechanismus der gleichzeitigen JUC-Programmierung

Inhaltsverzeichnis

1. Unterbrechungsmechanismus

1.1 Interrupt-Prinzip

1.2 Interrupt-Methode

1.2.1 Interrupt()-Methode

 1.2.2 isInterrupted()-Methode

1.2.3 Thread.interrupted()-Methode

1.3 Interrupts richtig behandeln

1.4 Hören Sie auf, laufende Threads zu unterbrechen

1.4.1 volatil

1.4.2 Atomare Klassen


1. Unterbrechungsmechanismus

Bei der gleichzeitigen Programmierung kann die Ausführung eines Threads durch einen anderen Thread unterbrochen werden. Diese Unterbrechung wird als „Unterbrechung“ bezeichnet. Unterbrechung ist ein Kommunikationsmechanismus zwischen Threads, der es einem Thread ermöglicht, einen anderen Thread zu benachrichtigen und ihn aufzufordern, seine aktuelle Arbeit zu stoppen und einige andere Vorgänge auszuführen. Der Interrupt-Mechanismus in JUC wird interrupt()durch Methoden implementiert.

1.1 Interrupt-Prinzip

Die Unterbrechung wird durch das Interrupt-Flag-Bit des Threads erreicht. Jedem Java-Thread ist ein boolesches Interrupt-Flag zugeordnet. Wenn ein Thread interrupt()eine Methode aufruft, setzt er das Interrupt-Flag-Bit des Ziel-Threads auf true, um anzuzeigen, dass der Thread unterbrochen wurde. Der unterbrochene Thread kann dann die Interrupt-Anforderung erkennen, indem er seinen eigenen Interrupt-Status überprüft.

1.2 Interrupt-Methode

1.2.1  interrupt()Methode

interrupt()Methoden sind ThreadInstanzmethoden einer Klasse, die verwendet werden, um den aktuellen Thread zu unterbrechen oder einen Ziel-Thread anzugeben. Es wird wie folgt deklariert:

public void interrupt()

 Durch den Aufruf interrupt()der Methode wird das Interrupt-Flag-Bit des Ziel-Threads auf gesetzt true. Wenn sich der Zielthread in einem blockierten Zustand befindet (z. B. beim Aufrufen von Methoden wie sleep(), usw.), löst er sofort eine Ausnahme aus und kehrt aus dem blockierten Zustand zurück. Nachdem der Thread im blockierten Zustand unterbrochen wurde und eine Ausnahme ausgelöst wurde, sollten wir den unterbrochenen Zustand wiederherstellen. Dies liegt daran, dass nach dem Auslösen der Ausnahme das Interrupt-Flag gelöscht wird. Wenn wir möchten, dass der nachfolgende Code den Interrupt-Status korrekt erkennt, müssen wir das Interrupt-Flag erneut manuell setzen.wait()join()InterruptedExceptionInterruptedException

catch (InterruptedException e) {
    // 恢复中断状态
    Thread.currentThread().interrupt();
}

 1.2.2   isInterrupted()Methode

isInterrupted()Methode ist Threadeine Instanzmethode der Klasse, die zum Abfragen des Interrupt-Status des aktuellen Threads verwendet wird. Es wird wie folgt deklariert:

public boolean isInterrupted()

 Die aufrufende isInterrupted()Methode gibt das Interrupt-Flag-Bit des aktuellen Threads zurück. Beachten Sie, dass durch den Aufruf dieser Methode das Interrupt-Flag nicht gelöscht wird.

1.2.3   Thread.interrupted()Methode

Thread.interrupted()Die Methode ist Threadeine statische Methode der Klasse, mit der der Interrupt-Status des aktuellen Threads abgefragt und das Interrupt-Flag-Bit gelöscht wird. Es wird wie folgt deklariert:

public static boolean interrupted()

Die aufrufende Thread.interrupted()Methode gibt den Interrupt-Status des aktuellen Threads zurück und setzt das Interrupt-Flag-Bit des aktuellen Threads auf zurück false.

1.3 Interrupts richtig behandeln

Am Schlüsselpunkt der Thread-Ausführung sollten wir den Interrupt-Status des Threads überprüfen und entsprechend der Situation entsprechend reagieren. Wenn wir beispielsweise eine Aufgabe in einer Schleife ausführen, können wir isInterrupted()die Methode verwenden, um den Interrupt-Status zu überprüfen. Wenn wir feststellen, dass der Thread unterbrochen wurde, können wir die Schleife beenden und den Thread rechtzeitig verlassen.

public void run() {
    while (!Thread.currentThread().isInterrupted()) {
        // 执行任务...
    }
}

 Manchmal übergeben wir das Interrupt-Flag-Bit an andere Methoden oder Objekte. Nach der Verarbeitung der Interrupt-Logik sollten wir den Interrupt-Status löschen, um nachfolgende Interrupt-Beurteilungen nicht zu beeinträchtigen. Mit dieser Methode kann Thread.interrupted()das Interrupt-Flag-Bit gelöscht werden.

 Thread th = new Thread(() -> {
           while (!Thread.interrupted()){
               System.out.println(Thread.currentThread().getName());
               Thread.currentThread().interrupt();
           }
        }, "th");
        th.start();

1.4 Hören Sie auf, laufende Threads zu unterbrechen

1.4.1 volatil

volatileIst ein Schlüsselwort in Java, das zum Deklarieren von Variablen verwendet wird. Seine Hauptfunktion besteht darin, sicherzustellen, dass volatiledie geänderte Variable für alle Threads sichtbar ist. Das heißt, jedes Mal, wenn volatiledie Variable gelesen wird, wird der neueste Wert direkt aus dem Hauptspeicher abgerufen, anstatt den lokalen Cache-Wert des Threads zu verwenden. Wenn in einer Multithread-Umgebung ein Thread volatileden Wert der geänderten Variablen ändert, wird der Wert sofort im Hauptspeicher aktualisiert, andere Threads werden benachrichtigt und andere Threads sehen den neuesten Wert, wenn sie die Variable lesen. Dadurch wird sichergestellt, dass Änderungen an der Variablen für alle Threads sichtbar sind. volatileEs kann auch die Neuanordnung von Anweisungen verhindern und sicherstellen, dass volatiledie Lese- und Schreibvorgänge der geänderten Variablen in Ordnung sind und keine unerwarteten Ergebnisse auftreten.

public class Test {

    private static volatile boolean key=false;
    public static void main(String[] args) throws InterruptedException {
             new Thread(()->{
                 while (true){
                     if(key){
                         System.out.println(Thread.currentThread().getName()+ "终止");
                         break;
                     }
                     System.out.println(Thread.currentThread().getName()+" 执行");
                 }
             }).start();
             
             new Thread(()->{
                 key=true;
             }).start();
    }
}

1.4.2 Atomare Klassen

Atomare Klassen sind eine Reihe von Werkzeugklassen, die von JUC zur Implementierung atomarer Operationen bereitgestellt werden und die Atomizität in bestimmten Operationen gewährleisten. Die Atomklasse implementiert atomare Operationen über den CAS-Algorithmus (Compare and Swap). CAS ist eine optimistische Sperrtechnologie, die threadsichere gleichzeitige Operationen ohne Verwendung von Sperren implementieren kann.

Zu den häufig verwendeten Atomklassen gehören: AtomicInteger, AtomicLongusw.AtomicBoolean

public class Test {

    private static AtomicBoolean atomicBoolean=new AtomicBoolean(false);
    public static void main(String[] args) throws InterruptedException {
             new Thread(()->{
                 while (true){
                     if(atomicBoolean.get()){
                         System.out.println(Thread.currentThread().getName()+ "终止");
                         break;
                     }
                     System.out.println(Thread.currentThread().getName()+" 执行");
                 }
             }).start();

             new Thread(()->{
                atomicBoolean.set(true);
             }).start();
    }
}

Der dritte Fall besteht darin, die am Anfang des Artikels eingeführte Interrupt-Methode zu verwenden. hier weggelassen.

Ich denke du magst

Origin blog.csdn.net/qq_43649937/article/details/131996215
Empfohlen
Rangfolge