Inhaltsverzeichnis
1.2.3 Thread.interrupted()-Methode
1.3 Interrupts richtig behandeln
1.4 Hören Sie auf, laufende Threads zu unterbrechen
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 Thread
Instanzmethoden 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()
InterruptedException
InterruptedException
catch (InterruptedException e) {
// 恢复中断状态
Thread.currentThread().interrupt();
}
1.2.2 isInterrupted()
Methode
isInterrupted()
Methode ist Thread
eine 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 Thread
eine 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
volatile
Ist ein Schlüsselwort in Java, das zum Deklarieren von Variablen verwendet wird. Seine Hauptfunktion besteht darin, sicherzustellen, dass volatile
die geänderte Variable für alle Threads sichtbar ist. Das heißt, jedes Mal, wenn volatile
die 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 volatile
den 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. volatile
Es kann auch die Neuanordnung von Anweisungen verhindern und sicherstellen, dass volatile
die 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
, AtomicLong
usw.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.