En la sección anterior "Interrupción de subprocesos", explicamos cómo interrumpir un subproceso en ejecución y qué debemos hacer con el subproceso para interrumpir el subproceso. En general, podemos utilizar el mecanismo de interrupción introducido en la sección anterior. Sin embargo, si el hilo implementa un algoritmo complejo que se distribuye entre múltiples métodos, o si hay una llamada recursiva en la llamada al método, deberíamos usar una mejor manera de controlar la interrupción del hilo. Para ello, Java proporciona InterruptedException. Esta excepción se puede generar cuando se detecta y captura una solicitud de interrupción en el método run().
En esta sección, usaremos un hilo para buscar archivos en un directorio específico y sus subdirectorios para demostrar el control de la interrupción del hilo mediante InterruptedException.
lo sabes
Siga los pasos que se muestran a continuación para implementar el programa de muestra.
1. Cree una clase llamada FileSearch e implemente la interfaz Runnable. El código es el siguiente:
Copie el código de código de la siguiente manera:
la clase pública FileSearch implementa Runnable {
2. Declare dos variables, una para el nombre del archivo a buscar y otra para inicializar el directorio a buscar; implemente el constructor de la clase e inicialice las dos variables recién declaradas con los parámetros del constructor. El código es el siguiente:
Copie el código de código de la siguiente manera:
ruta de inicio de cadena privada;
nombre de archivo de cadena privada;
public FileSearch(String initPath, String fileName) {
this.initPath = initPath;
this.fileName = fileName;
}
3. Implemente el método run(), que comprueba si fileName es un nombre de ruta. Si es así, llame al método directorioProcess() para su procesamiento. El método directorioProcess() arroja InterruptedException, por lo que debemos detectar la excepción. El código es el siguiente:
Copie el código de código de la siguiente manera:
@Anular
ejecución pública vacía() {
Archivo archivo = nuevo archivo (initPath);
si (archivo.isDirectory()) {
intentar {
directorioProceso(archivo);
} captura (Excepción interrumpida e) {
System.out.printf("%s: La búsqueda ha sido interrumpida",
Thread.currentThread().getName());
}
}
}
En el artículo original, el nombre del método mencionado es ProcessDirectory(). Sin embargo, según el procedimiento siguiente, se trata de un error administrativo. Así que corrígelo.
4. Implemente el método directorioProcess(). Este método lee todos los archivos y subdirectorios en el directorio especificado y luego los procesa. Para cada directorio, este método realiza una llamada recursiva para procesar el directorio especificado por el parámetro. Para cada archivo, este método llama al método fileProcess(). Después de procesar todos los directorios y archivos, este método verificará si el hilo está interrumpido, lo que generará una excepción InterruptedException. El código es el siguiente:
Copie el código de código de la siguiente manera:
/**
* Procesar un directorio
*
* @param directorio de archivos a procesar
* @throws Excepción interrumpida
*/
proceso de directorio vacío privado (archivo de archivo) lanza InterruptedException {
Archivo[] lista = archivo.listFiles();
si (nulo! = lista) {
for (int i = 0; i < lista.longitud; i++) {
if (lista[i].isDirectorio()) {
directorioProceso(lista[i]);
} demás {
fileProcess(lista[i]);
}
}
}
si (Thread.interrupted()) {
lanzar una nueva excepción interrumpida();
}
}
5. Implemente el método fileProcess(), que compara el archivo que se está procesando con el nombre del archivo que se va a encontrar. Si los nombres de los archivos son iguales, se imprime un mensaje en la consola. Luego, el hilo verifica si fue interrumpido y, de ser así, arroja una InterruptedException. El código es el siguiente:
Copie el código de código de la siguiente manera:
/**
* Archivos procesados
*
* Archivo @param archivo a procesar
* @throws Excepción interrumpida
*/
proceso de archivo vacío privado (archivo de archivo) lanza InterruptedException {
if (archivo.getName().equals(nombredearchivo)) {
System.out.printf("%s: %s/n",
Thread.currentThread().getName(),
archivo.getAbsolutePath());
}
si (Thread.interrupted()) {
lanzar una nueva excepción interrumpida();
}
}
6. Ahora, implemente la clase principal del ejemplo e implemente el método main(). El código es el siguiente:
Copie el código de código de la siguiente manera:
clase pública principal {
público estático vacío principal (String [] argumentos) {
7. Cree e inicialice el objeto FileSearch y luego cree un objeto Thread para realizar la tarea. Entonces, inicia el hilo. El código es el siguiente:
Copie el código de código de la siguiente manera:
FileSearch fileSearch = nuevo FileSearch("C://", "autoexec.bat");
Hilo hilo = nuevo hilo (fileSearch);
hilo.start();
8. Espere diez segundos y luego interrumpa el hilo. El código es el siguiente:
Copie el código de código de la siguiente manera:
intentar {
Unidad de tiempo.SEGUNDOS.dormir(10);
} captura (Excepción interrumpida e) {
e.printStackTrace();
}
hilo.interrupt();
9. Ejecute el ejemplo y vea los resultados.
saber por qué
El siguiente es el resultado de la ejecución del hilo. Se puede ver en el resultado cómo finaliza la ejecución del hilo cuando FileSearch detecta que ha sido interrumpido.
Copie el código de código de la siguiente manera:
Hilo-0: C:/autoexec.bat
Hilo-0: La búsqueda ha sido interrumpida
En este ejemplo, utilizamos excepciones de Java para controlar la interrupción del hilo. Cuando ejecuta el ejemplo, el programa comprueba si el directorio especificado y sus subdirectorios contienen el archivo de destino. Por ejemplo, si ingresa /b/c/d, el programa llamará recursivamente al método directorioProcess() tres veces. Cuando el hilo detecta que ha sido interrumpido, se lanzará una InterruptedException. No importa cuántas llamadas recursivas se realicen, el programa comenzará a ejecutar el método run().
interminable
Las excepciones InterruptedException generalmente las generan las API de concurrencia de Java, como el método sleep().
Usar doctrina
Este artículo está traducido del "Libro de cocina de concurrencia de Java 7" (D Gua Ge lo robó como "Colección de ejemplos de concurrencia de Java 7") y solo se utiliza como material de aprendizaje. No puede utilizarse con fines comerciales sin autorización.
Pequeño éxito
El código completo de la clase FileSearch es el siguiente:
paquete com.diguage.books.concurrencycookbook.chapter1.recipe4;
importar java.io.File;
/**
* Fecha: 2013-09-18
* Hora: 18:21
*/
la clase pública FileSearch implementa Runnable {
ruta de inicio de cadena privada;
nombre de archivo de cadena privada;
/**
* Constructor de inicialización
*
* @param initPath El directorio a buscar
* @param fileName El nombre del archivo que se va a encontrar
*/
public FileSearch(String initPath, String fileName) {
this.initPath = initPath;
this.fileName = fileName;
}
@Anular
ejecución pública vacía() {
Archivo archivo = nuevo archivo (initPath);
si (archivo.isDirectory()) {
intentar {
directorioProceso(archivo);
} captura (Excepción interrumpida e) {
System.out.printf("%s: La búsqueda ha sido interrumpida",
Thread.currentThread().getName());
}
}
}
/**
* Procesar un directorio
*
* @param directorio de archivos a procesar
* @throws Excepción interrumpida
*/
proceso de directorio vacío privado (archivo de archivo) lanza InterruptedException {
Archivo[] lista = archivo.listFiles();
si (nulo! = lista) {
for (int i = 0; i < lista.longitud; i++) {
if (lista[i].isDirectorio()) {
directorioProceso(lista[i]);
} demás {
fileProcess(lista[i]);
}
}
}
si (Thread.interrupted()) {
lanzar una nueva excepción interrumpida();
}
}
/**
* Archivos procesados
*
* Archivo @param archivo a procesar
* @throws Excepción interrumpida
*/
proceso de archivo vacío privado (archivo de archivo) lanza InterruptedException {
if (archivo.getName().equals(nombredearchivo)) {
System.out.printf("%s: %s/n",
Thread.currentThread().getName(),
archivo.getAbsolutePath());
}
si (Thread.interrupted()) {
lanzar una nueva excepción interrumpida();
}
}
}
El código completo de la clase principal.
Copie el código de código de la siguiente manera:
paquete com.diguage.books.concurrencycookbook.chapter1.recipe4;
importar java.util.concurrent.TimeUnit;
/**
* Fecha: 2013-09-18
* Hora: 19:28
*/
clase pública principal {
público estático vacío principal (String [] argumentos) {
FileSearch fileSearch = nuevo FileSearch("C://", "autoexec.bat");
Hilo hilo = nuevo hilo (fileSearch);
hilo.start();
intentar {
Unidad de tiempo.SEGUNDOS.dormir(10);
} captura (Excepción interrumpida e) {
e.printStackTrace();
}
hilo.interrupt();
}
}