이전 섹션 "스레드 중단"에서는 실행 중인 스레드를 중단하는 방법과 스레드를 중단하기 위해 Thread에 수행해야 하는 작업에 대해 설명했습니다. 일반적으로 이전 섹션에서 소개한 인터럽트 메커니즘을 사용할 수 있습니다. 그러나 스레드가 여러 메서드에 분산된 복잡한 알고리즘을 구현하거나 메서드 호출에 재귀 호출이 있는 경우 스레드 중단을 제어하는 더 나은 방법을 사용해야 합니다. 이를 위해 Java에서는 InterruptedException을 제공합니다. 이 예외는 인터럽트 요청이 감지되어 run() 메서드에서 포착될 때 발생할 수 있습니다.
이 섹션에서는 InterruptedException을 사용하여 스레드 중단을 제어하는 방법을 보여주기 위해 스레드를 사용하여 지정된 디렉터리와 해당 하위 디렉터리에서 파일을 검색합니다.
알아요
샘플 프로그램을 구현하려면 아래 단계를 따르세요.
1. FileSearch라는 클래스를 생성하고 Runnable 인터페이스를 구현합니다. 코드는 다음과 같습니다:
다음과 같이 코드 코드를 복사합니다.
공개 클래스 FileSearch는 Runnable을 구현합니다.
2. 검색할 파일명 변수와 검색할 디렉터리 초기화 변수 2개를 선언하고, 방금 선언한 변수 2개를 생성자의 매개변수로 초기화합니다. 코드는 다음과 같습니다:
다음과 같이 코드 코드를 복사합니다.
개인 문자열 initPath;
개인 문자열 파일명;
공개 FileSearch(문자열 initPath, 문자열 파일 이름) {
this.initPath = initPath;
this.fileName = 파일이름;
}
3. fileName이 경로 이름인지 확인하는 run() 메서드를 구현합니다. 그렇다면 처리를 위해 DirectoryProcess() 메서드를 호출하세요. DirectoryProcess() 메서드는 InterruptedException을 발생시키므로 예외를 포착해야 합니다. 코드는 다음과 같습니다:
다음과 같이 코드 코드를 복사합니다.
@보수
공개 무효 실행() {
파일 파일 = 새 파일(initPath);
if (file.isDirectory()) {
노력하다 {
디렉토리프로세스(파일);
} 잡기(InterruptedException e) {
System.out.printf("%s: 검색이 중단되었습니다.",
Thread.currentThread().getName());
}
}
}
원본 기사에서 언급된 메서드 이름은 processDirectory()입니다. 그러나 아래 절차에 따르면 사무적인 오류입니다. 그러니 수정하세요.
4. DirectoryProcess() 메서드를 구현합니다. 이 메서드는 지정된 디렉터리의 모든 파일과 하위 디렉터리를 읽은 다음 처리합니다. 각 디렉터리에 대해 이 메서드는 매개변수로 지정된 디렉터리를 처리하기 위해 재귀 호출을 수행합니다. 각 파일에 대해 이 메서드는 fileProcess() 메서드를 호출합니다. 모든 디렉터리와 파일을 처리한 후 이 메서드는 스레드가 중단되었는지 여부를 확인하여 InterruptedException 예외를 발생시킵니다. 코드는 다음과 같습니다:
다음과 같이 코드 코드를 복사합니다.
/**
* 디렉토리 처리
*
* 처리할 @param 파일 디렉터리
* @throws InterruptedException
*/
개인 무효 디렉토리 프로세스(파일 파일)가 InterruptedException을 발생시킵니다.
파일[] 목록 = file.listFiles();
if (null != 목록) {
for (int i = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
디렉토리프로세스(목록[i]);
} 또 다른 {
fileProcess(목록[i]);
}
}
}
if (Thread.interrupted()) {
새로운 InterruptedException()을 던져라;
}
}
5. 처리 중인 파일과 찾을 파일 이름을 비교하는 fileProcess() 메서드를 구현합니다. 파일 이름이 동일하면 메시지가 콘솔에 인쇄됩니다. 그런 다음 스레드는 중단되었는지 확인하고 중단된 경우 InterruptedException을 발생시킵니다. 코드는 다음과 같습니다:
다음과 같이 코드 코드를 복사합니다.
/**
* 처리된 파일
*
* @param 파일 처리할 파일
* @throws InterruptedException
*/
private void fileProcess(파일 파일)가 InterruptedException을 발생시킵니다.
if (file.getName().equals(fileName)) {
System.out.printf("%s : %s/n",
Thread.currentThread().getName(),
file.getAbsolutePath());
}
if (Thread.interrupted()) {
새로운 InterruptedException()을 던져라;
}
}
6. 이제 예제의 메인 클래스를 구현하고 main() 메서드를 구현합니다. 코드는 다음과 같습니다:
다음과 같이 코드 코드를 복사합니다.
공개 클래스 메인 {
공개 정적 무효 메인(String[] args) {
7. FileSearch 객체를 생성 및 초기화한 다음 작업을 수행하기 위한 Thread 객체를 생성합니다. 그런 다음 스레드를 시작하십시오. 코드는 다음과 같습니다:
다음과 같이 코드 코드를 복사합니다.
FileSearch fileSearch = new FileSearch("C://", "autoexec.bat");
스레드 스레드 = new Thread(fileSearch);
thread.start();
8. 10초 동안 기다린 후 스레드를 중단합니다. 코드는 다음과 같습니다:
다음과 같이 코드 코드를 복사합니다.
노력하다 {
TimeUnit.SECONDS.sleep(10);
} 잡기(InterruptedException e) {
e.printStackTrace();
}
스레드.인터럽트();
9. 예제를 실행하고 결과를 확인합니다.
왜인지 알아
다음은 Thread 실행 결과이다. FileSearch가 스레드 실행이 중단되었음을 감지하면 스레드 실행이 어떻게 종료되는지 출력에서 볼 수 있습니다.
다음과 같이 코드 코드를 복사합니다.
스레드-0: C:/autoexec.bat
스레드-0: 검색이 중단되었습니다.
이 예에서는 Java 예외를 사용하여 스레드 중단을 제어합니다. 예제를 실행하면 프로그램은 지정된 디렉터리와 해당 하위 디렉터리에 대상 파일이 포함되어 있는지 확인합니다. 예를 들어, /b/c/d를 입력하면 프로그램은 DirectoryProcess() 메서드를 세 번 반복적으로 호출합니다. 스레드가 중단되었음을 감지하면 InterruptedException이 발생합니다. 재귀 호출이 아무리 많이 수행되더라도 프로그램은 run() 메서드 실행을 시작합니다.
끝나지 않는
InterruptedException 예외는 일반적으로 sleep() 메소드와 같은 Java 동시성 API에 의해 발생됩니다.
교리를 사용하라
이 글은 "Java 7 Concurrency Cookbook"(D Gua Ge가 "Java7 Concurrency 예제 모음"으로 훔쳤습니다)을 번역한 것이며, 학습 자료로만 사용됩니다. 허가 없이 상업적인 목적으로 사용할 수 없습니다.
작은 성공
FileSearch 클래스의 전체 코드는 다음과 같습니다.
패키지 com.diguage.books.concurrencycookbook.chapter1.recipe4;
java.io.파일 가져오기;
/**
* 날짜: 2013-09-18
* 시간 : 18:21
*/
공개 클래스 FileSearch는 Runnable을 구현합니다.
개인 문자열 initPath;
개인 문자열 파일명;
/**
* 초기화 생성자
*
* @param initPath 검색할 디렉터리
* @param fileName 찾을 파일 이름
*/
공개 FileSearch(문자열 initPath, 문자열 파일 이름) {
this.initPath = initPath;
this.fileName = 파일이름;
}
@보수
공개 무효 실행() {
파일 파일 = 새 파일(initPath);
if (file.isDirectory()) {
노력하다 {
디렉토리프로세스(파일);
} 잡기(InterruptedException e) {
System.out.printf("%s: 검색이 중단되었습니다.",
Thread.currentThread().getName());
}
}
}
/**
* 디렉토리 처리
*
* 처리할 @param 파일 디렉터리
* @throws InterruptedException
*/
개인 무효 디렉토리 프로세스(파일 파일)가 InterruptedException을 발생시킵니다.
파일[] 목록 = file.listFiles();
if (null != 목록) {
for (int i = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
디렉토리프로세스(목록[i]);
} 또 다른 {
fileProcess(목록[i]);
}
}
}
if (Thread.interrupted()) {
새로운 InterruptedException()을 던져라;
}
}
/**
* 처리된 파일
*
* @param 파일 처리할 파일
* @throws InterruptedException
*/
private void fileProcess(파일 파일)가 InterruptedException을 발생시킵니다.
if (file.getName().equals(fileName)) {
System.out.printf("%s : %s/n",
Thread.currentThread().getName(),
file.getAbsolutePath());
}
if (Thread.interrupted()) {
새로운 InterruptedException()을 던져라;
}
}
}
Main 클래스의 전체 코드
다음과 같이 코드 코드를 복사합니다.
패키지 com.diguage.books.concurrencycookbook.chapter1.recipe4;
import java.util.concurrent.TimeUnit;
/**
* 날짜: 2013-09-18
* 시간 : 19:28
*/
공개 클래스 메인 {
공개 정적 무효 메인(String[] args) {
FileSearch fileSearch = new FileSearch("C://", "autoexec.bat");
스레드 스레드 = new Thread(fileSearch);
thread.start();
노력하다 {
TimeUnit.SECONDS.sleep(10);
} 잡기(InterruptedException e) {
e.printStackTrace();
}
스레드.인터럽트();
}
}