Na seção anterior "Interrupção de Thread", explicamos como interromper um thread em execução e o que devemos fazer com Thread para interromper o thread. Em geral, podemos usar o mecanismo de interrupção apresentado na seção anterior. No entanto, se o thread implementar um algoritmo complexo distribuído entre vários métodos, ou se houver uma chamada recursiva na chamada do método, devemos usar uma maneira melhor de controlar a interrupção do thread. Para este propósito, Java fornece InterruptedException. Esta exceção pode ser lançada quando uma solicitação de interrupção é detectada e capturada no método run().
Nesta seção, usaremos um thread para procurar arquivos em um diretório especificado e seus subdiretórios para demonstrar o controle da interrupção do thread usando InterruptedException.
saiba disso
Siga as etapas mostradas abaixo para implementar o programa de exemplo.
1. Crie uma classe chamada FileSearch e implemente a interface Runnable. O código é o seguinte:
Copie o código do código da seguinte forma:
classe pública FileSearch implementa Runnable {
2. Declare duas variáveis, uma para o nome do arquivo a ser pesquisado e outra para inicializar o diretório a ser pesquisado, implemente o construtor da classe e inicialize as duas variáveis recém-declaradas com os parâmetros do construtor; O código é o seguinte:
Copie o código do código da seguinte forma:
private String initPath;
private String nomeArquivo;
public FileSearch(String caminhoInit, String nomeArquivo) {
this.initPath = initPath;
this.fileName = nomedoarquivo;
}
3. Implemente o método run(), que verifica se fileName é um nome de caminho. Nesse caso, chame o método directoryProcess() para processamento. O método directoryProcess() lança InterruptedException, então precisamos capturar a exceção. O código é o seguinte:
Copie o código do código da seguinte forma:
@Substituir
execução void pública() {
Arquivo arquivo = novo arquivo(initPath);
if (arquivo.isDirectory()) {
tentar {
diretórioProcess(arquivo);
} catch (InterruptedException e) {
System.out.printf("%s: A busca foi interrompida",
Thread.currentThread().getName());
}
}
}
No artigo original, o nome do método mencionado é processDirectory(). Porém, de acordo com o procedimento abaixo, trata-se de um erro administrativo. Então corrija.
4. Implemente o método directoryProcess(). Este método lê todos os arquivos e subdiretórios no diretório especificado e os processa. Para cada diretório, este método faz uma chamada recursiva para processar o diretório especificado pelo parâmetro. Para cada arquivo, este método chama o método fileProcess(). Após processar todos os diretórios e arquivos, este método verificará se o thread foi interrompido, o que lançará uma exceção InterruptedException. O código é o seguinte:
Copie o código do código da seguinte forma:
/**
* Processar um diretório
*
* @param diretório do arquivo a ser processado
* @throws InterruptedException
*/
private void directoryProcess (arquivo arquivo) lança InterruptedException {
Arquivo[] lista = arquivo.listArquivos();
if (nulo! = lista) {
for (int i = 0; i < lista.comprimento; i++) {
if (lista[i].isDirectory()) {
diretórioProcess(lista[i]);
} outro {
arquivoProcess(lista[i]);
}
}
}
if (Thread.interrupted()) {
lançar new InterruptedException();
}
}
5. Implemente o método fileProcess(), que compara o arquivo que está sendo processado com o nome do arquivo a ser encontrado. Se os nomes dos arquivos forem iguais, uma mensagem será impressa no console. O thread então verifica se foi interrompido e, em caso afirmativo, lança uma InterruptedException. O código é o seguinte:
Copie o código do código da seguinte forma:
/**
* Arquivos processados
*
* @param arquivo arquivo a ser processado
* @throws InterruptedException
*/
private void fileProcess(arquivo de arquivo) lança InterruptedException {
if (arquivo.getNome().equals(nomedoarquivo)) {
System.out.printf("%s : %s/n",
Thread.currentThread().getName(),
arquivo.getAbsolutePath());
}
if (Thread.interrupted()) {
lançar new InterruptedException();
}
}
6. Agora, implemente a classe principal do exemplo e implemente o método main(). O código é o seguinte:
Copie o código do código da seguinte forma:
classe pública Principal {
public static void main(String[] args) {
7. Crie e inicialize o objeto FileSearch e, em seguida, crie um objeto Thread para executar a tarefa. Então, inicie o tópico. O código é o seguinte:
Copie o código do código da seguinte forma:
FileSearch fileSearch = new FileSearch("C://", "autoexec.bat");
Thread thread = new Thread(fileSearch);
thread.start();
8. Aguarde dez segundos e interrompa o thread. O código é o seguinte:
Copie o código do código da seguinte forma:
tentar {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
9. Execute o exemplo e visualize os resultados.
sabe por que
A seguir está o resultado da execução do thread. Pode-se ver na saída como a execução do thread é encerrada quando o FileSearch detecta que foi interrompido.
Copie o código do código da seguinte forma:
Tópico-0: C:/autoexec.bat
Tópico-0: A pesquisa foi interrompida
Neste exemplo, usamos exceções Java para controlar a interrupção do thread. Ao executar o exemplo, o programa verifica se o diretório especificado e seus subdiretórios contêm o arquivo de destino. Por exemplo, se você inserir /b/c/d, o programa chamará recursivamente o método directoryProcess() três vezes. Quando o thread detectar que foi interrompido, uma InterruptedException será lançada. Não importa quantas chamadas recursivas sejam realizadas, o programa começará a executar o método run().
sem fim
As exceções InterruptedException geralmente são lançadas por APIs de simultaneidade Java, como o método sleep().
Usar doutrina
Este artigo foi traduzido do "Java 7 Concurrency Cookbook" (D Gua Ge o roubou como "Java7 Concurrency Sample Collection") e é usado apenas como material de aprendizagem. Não pode ser utilizado para quaisquer fins comerciais sem autorização.
Pequeno sucesso
O código completo da classe FileSearch é o seguinte:
pacote com.diguage.books.concurrencycookbook.chapter1.recipe4;
importar java.io.File;
/**
* Data: 18/09/2013
* Horário: 18h21
*/
classe pública FileSearch implementa Runnable {
private String initPath;
private String nomeArquivo;
/**
* Construtor de inicialização
*
* @param initPath O diretório a ser pesquisado
* @param fileName O nome do arquivo a ser encontrado
*/
public FileSearch(String caminhoInit, String nomeArquivo) {
this.initPath = initPath;
this.fileName = nomedoarquivo;
}
@Substituir
execução void pública() {
Arquivo arquivo = novo arquivo(initPath);
if (arquivo.isDirectory()) {
tentar {
diretórioProcess(arquivo);
} catch (InterruptedException e) {
System.out.printf("%s: A busca foi interrompida",
Thread.currentThread().getName());
}
}
}
/**
* Processar um diretório
*
* @param diretório do arquivo a ser processado
* @throws InterruptedException
*/
private void directoryProcess (arquivo arquivo) lança InterruptedException {
Arquivo[] lista = arquivo.listArquivos();
if (nulo! = lista) {
for (int i = 0; i < lista.comprimento; i++) {
if (lista[i].isDirectory()) {
diretórioProcess(lista[i]);
} outro {
arquivoProcess(lista[i]);
}
}
}
if (Thread.interrupted()) {
lançar new InterruptedException();
}
}
/**
* Arquivos processados
*
* @param arquivo arquivo a ser processado
* @throws InterruptedException
*/
private void fileProcess(arquivo de arquivo) lança InterruptedException {
if (arquivo.getNome().equals(nomedoarquivo)) {
System.out.printf("%s : %s/n",
Thread.currentThread().getName(),
arquivo.getAbsolutePath());
}
if (Thread.interrupted()) {
lançar new InterruptedException();
}
}
}
O código completo da classe principal
Copie o código do código da seguinte forma:
pacote com.diguage.books.concurrencycookbook.chapter1.recipe4;
importar java.util.concurrent.TimeUnit;
/**
* Data: 18/09/2013
* Horário: 19h28
*/
classe pública Principal {
public static void main(String[] args) {
FileSearch fileSearch = new FileSearch("C://", "autoexec.bat");
Thread thread = new Thread(fileSearch);
thread.start();
tentar {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
}