Im vorherigen Abschnitt „Thread-Unterbrechung“ haben wir erklärt, wie man einen ausgeführten Thread unterbricht und was wir mit Thread tun müssen, um den Thread zu unterbrechen. Im Allgemeinen können wir den im vorherigen Abschnitt eingeführten Interrupt-Mechanismus verwenden. Wenn der Thread jedoch einen komplexen Algorithmus implementiert, der auf mehrere Methoden verteilt ist, oder wenn der Methodenaufruf einen rekursiven Aufruf enthält, sollten wir die Unterbrechung des Threads besser steuern. Zu diesem Zweck stellt Java eine InterruptedException zur Verfügung. Diese Ausnahme kann ausgelöst werden, wenn eine Interrupt-Anfrage erkannt und in der run()-Methode abgefangen wird.
In diesem Abschnitt verwenden wir einen Thread, um nach Dateien in einem angegebenen Verzeichnis und seinen Unterverzeichnissen zu suchen, um die Steuerung der Thread-Unterbrechung mithilfe von InterruptedException zu demonstrieren.
weiß es
Befolgen Sie die unten gezeigten Schritte, um das Beispielprogramm zu implementieren.
1. Erstellen Sie eine Klasse mit dem Namen FileSearch und implementieren Sie die Runnable-Schnittstelle. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
Die öffentliche Klasse FileSearch implementiert Runnable {
2. Deklarieren Sie zwei Variablen, eine für den zu durchsuchenden Dateinamen und eine für die Initialisierung des zu durchsuchenden Verzeichnisses. Implementieren Sie den Konstruktor der Klasse und initialisieren Sie die beiden gerade deklarierten Variablen mit den Parametern des Konstruktors. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
privater String initPath;
privater String fileName;
public FileSearch(String initPath, String fileName) {
this.initPath = initPath;
this.fileName = fileName;
}
3. Implementieren Sie die Methode run(), die prüft, ob fileName ein Pfadname ist. Rufen Sie in diesem Fall die Methode „directoryProcess()“ zur Verarbeitung auf. Die Methode „directoryProcess()“ löst eine InterruptedException aus, daher müssen wir die Ausnahme abfangen. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
@Override
public void run() {
Datei file = new File(initPath);
if (file.isDirectory()) {
versuchen {
Verzeichnisprozess(Datei);
} Catch (InterruptedException e) {
System.out.printf("%s: Die Suche wurde unterbrochen",
Thread.currentThread().getName());
}
}
}
Im Originalartikel lautet der Methodenname „processDirectory()“. Gemäß dem nachstehenden Verfahren handelt es sich jedoch um einen Schreibfehler. Also korrigiere es.
4. Implementieren Sie die Methode „directoryProcess()“. Diese Methode liest alle Dateien und Unterverzeichnisse im angegebenen Verzeichnis und verarbeitet sie anschließend. Für jedes Verzeichnis führt diese Methode einen rekursiven Aufruf durch, um das durch den Parameter angegebene Verzeichnis zu verarbeiten. Für jede Datei ruft diese Methode die Methode fileProcess() auf. Nach der Verarbeitung aller Verzeichnisse und Dateien prüft diese Methode, ob der Thread unterbrochen ist, was bedeutet, dass eine InterruptedException-Ausnahme ausgelöst wird. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
/**
* Verarbeiten Sie ein Verzeichnis
*
* @param-Dateiverzeichnis, das verarbeitet werden soll
* @throws InterruptedException
*/
private void DirectoryProcess(File file) throws InterruptedException {
File[] list = file.listFiles();
if (null != Liste) {
for (int i = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
Verzeichnisprozess(Liste[i]);
} anders {
fileProcess(list[i]);
}
}
}
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
5. Implementieren Sie die Methode fileProcess(), die die verarbeitete Datei mit dem zu findenden Dateinamen vergleicht. Wenn die Dateinamen gleich sind, wird eine Meldung an die Konsole ausgegeben. Der Thread prüft dann, ob er unterbrochen wurde, und löst in diesem Fall eine InterruptedException aus. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
/**
* Verarbeitete Dateien
*
* @param-Datei Datei, die verarbeitet werden soll
* @throws InterruptedException
*/
private void fileProcess(File file) löst InterruptedException {
if (file.getName().equals(fileName)) {
System.out.printf("%s : %s/n",
Thread.currentThread().getName(),
file.getAbsolutePath());
}
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
6. Implementieren Sie nun die Hauptklasse des Beispiels und implementieren Sie die Methode main(). Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse Main {
public static void main(String[] args) {
7. Erstellen und initialisieren Sie das FileSearch-Objekt und erstellen Sie dann ein Thread-Objekt, um die Aufgabe auszuführen. Dann starten Sie den Thread. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
FileSearch fileSearch = new FileSearch("C://", "autoexec.bat");
Thread thread = neuer Thread(fileSearch);
thread.start();
8. Warten Sie zehn Sekunden und unterbrechen Sie dann den Thread. Der Code lautet wie folgt:
Kopieren Sie den Codecode wie folgt:
versuchen {
TimeUnit.SECONDS.sleep(10);
} Catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
9. Führen Sie das Beispiel aus und sehen Sie sich die Ergebnisse an.
weiß warum
Das Folgende ist das Ergebnis der Thread-Ausführung. Aus der Ausgabe ist ersichtlich, wie die Thread-Ausführung beendet wird, wenn FileSearch erkennt, dass sie unterbrochen wurde.
Kopieren Sie den Codecode wie folgt:
Thread-0: C:/autoexec.bat
Thread-0: Die Suche wurde unterbrochen
In diesem Beispiel verwenden wir Java-Ausnahmen, um Thread-Unterbrechungen zu steuern. Wenn Sie das Beispiel ausführen, prüft das Programm, ob das angegebene Verzeichnis und seine Unterverzeichnisse die Zieldatei enthalten. Wenn Sie beispielsweise /b/c/d eingeben, ruft das Programm die Methode „directoryProcess()“ dreimal rekursiv auf. Wenn der Thread erkennt, dass er unterbrochen wurde, wird eine InterruptedException ausgelöst. Unabhängig davon, wie viele rekursive Aufrufe ausgeführt werden, beginnt das Programm mit der Ausführung der run()-Methode.
niemals enden
InterruptedException-Ausnahmen werden im Allgemeinen von Java-Parallelitäts-APIs wie der Methode „sleep()“ ausgelöst.
Nutzen Sie die Lehre
Dieser Artikel wurde aus dem „Java 7 Concurrency Cookbook“ übersetzt (D Gua Ge hat ihn als „Java7 Concurrency Beispielsammlung“ gestohlen) und dient nur als Lernmaterial. Es darf ohne Genehmigung nicht für kommerzielle Zwecke verwendet werden.
Kleiner Erfolg
Der vollständige Code der FileSearch-Klasse lautet wie folgt:
Paket com.diguage.books.concurrencycookbook.chapter1.recipe4;
java.io.File importieren;
/**
* Datum: 18.09.2013
* Zeit: 18:21
*/
Die öffentliche Klasse FileSearch implementiert Runnable {
privater String initPath;
privater String fileName;
/**
* Initialisierungskonstruktor
*
* @param initPath Das zu durchsuchende Verzeichnis
* @param fileName Der Name der zu findenden Datei
*/
public FileSearch(String initPath, String fileName) {
this.initPath = initPath;
this.fileName = fileName;
}
@Override
public void run() {
Datei file = new File(initPath);
if (file.isDirectory()) {
versuchen {
Verzeichnisprozess(Datei);
} Catch (InterruptedException e) {
System.out.printf("%s: Die Suche wurde unterbrochen",
Thread.currentThread().getName());
}
}
}
/**
* Verarbeiten Sie ein Verzeichnis
*
* @param-Dateiverzeichnis, das verarbeitet werden soll
* @throws InterruptedException
*/
private void DirectoryProcess(File file) throws InterruptedException {
File[] list = file.listFiles();
if (null != Liste) {
for (int i = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
Verzeichnisprozess(Liste[i]);
} anders {
fileProcess(list[i]);
}
}
}
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
/**
* Verarbeitete Dateien
*
* @param-Datei Datei, die verarbeitet werden soll
* @throws InterruptedException
*/
private void fileProcess(File file) löst InterruptedException {
if (file.getName().equals(fileName)) {
System.out.printf("%s : %s/n",
Thread.currentThread().getName(),
file.getAbsolutePath());
}
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
}
Der vollständige Code der Hauptklasse
Kopieren Sie den Codecode wie folgt:
Paket com.diguage.books.concurrencycookbook.chapter1.recipe4;
import java.util.concurrent.TimeUnit;
/**
* Datum: 18.09.2013
* Zeit: 19:28
*/
öffentliche Klasse Main {
public static void main(String[] args) {
FileSearch fileSearch = new FileSearch("C://", "autoexec.bat");
Thread thread = neuer Thread(fileSearch);
thread.start();
versuchen {
TimeUnit.SECONDS.sleep(10);
} Catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
}