Java 동시 프로그래밍 예제(4): 제어 가능한 스레드 인터럽트

이전 섹션 "스레드 인터럽트"에서 실행 중인 스레드를 중단하는 방법과 스레드를 중단하기 위해 Thread에 대해 어떤 조치를 취해야 하는지 설명합니다.일반적인 상황에서 우리는 이전 절에서 소개한 중단 메커니즘을 사용할 수 있다.그러나 만약에 스레드가 여러 가지 방법에 분배된 복잡한 알고리즘을 실현하거나 방법 호출에 귀속 호출이 있다면 우리는 더욱 좋은 방식으로 스레드의 중단을 제어해야 한다.이를 위해 Java는 InterruptedException 이상을 제공합니다.중단 요청이 발견되면 이 이상을 던지고run () 방법에서 포획할 수 있습니다.
이 절에서, 우리는 지정한 디렉터리와 하위 디렉터리의 파일을 찾아서 인터럽트 exception 이상을 사용하여 디렉터리 중단을 제어하는 것을 보여 줍니다.
그 사실을 알다
아래와 같은 절차에 따라 예시 절차를 실현하다.
1. FileSearch라는 클래스를 만들고 Runnable 인터페이스를 실현합니다.코드는 다음과 같습니다.

public class FileSearch implements Runnable {
2. 두 개의 변수, 하나는 찾아야 할 파일 이름, 하나는 초기화하는 디렉터리입니다.클래스의 구조 함수를 실현하고 구조 함수의 매개 변수로 방금 설명한 두 변수를 초기화합니다.코드는 다음과 같습니다.

private String initPath;
private String fileName;

public FileSearch(String initPath, String fileName) {
    this.initPath = initPath;
    this.fileName = fileName;
}

3. run () 방법을 실행합니다. 이 방법은 fileName이 경로 이름인지 확인합니다.만약 그렇다면directoryProcess () 방법을 호출하여 처리합니다.directory Process () 방법은 Interrupted Exception 이상을 던지기 때문에 이 이상을 포착해야 합니다.코드는 다음과 같습니다.

@Override
public void run() {
    File file = new File(initPath);
    if (file.isDirectory()) {
        try {
            directoryProcess(file);
        } catch (InterruptedException e) {
            System.out.printf("%s: The search has been interrupted",
                    Thread.currentThread().getName());
        }
    }
}
원문에서 언급한 방법의 이름은 processDirectory () 입니다.그러나 다음 문장의 절차에 따라 오류에 속한다.그러므로 고치다.
4. directoryProcess () 방법을 실현한다.이 방법은 지정한 디렉터리 아래의 모든 파일과 하위 디렉터리를 읽고 처리합니다.매개 디렉터리에 대해 이 방법은 매개 변수가 지정한 디렉터리를 처리하기 위해 귀속 호출을 한다.모든 파일에 대해 이 방법은 fileProcess () 방법을 호출합니다.모든 디렉터리와 파일을 처리한 후, 이 방법은 라인이 중단되었는지 확인합니다. 이것은 인터럽트 exception 이상을 던지는 것입니다.코드는 다음과 같습니다.

/**
 *
 *
 * @param file
 * @throws InterruptedException
 */
private void directoryProcess(File file) throws InterruptedException {
    File[] list = file.listFiles();
    if (null != list) {
        for (int i = 0; i < list.length; i++) {
            if (list[i].isDirectory()) {
                directoryProcess(list[i]);
            } else {
                fileProcess(list[i]);
            }

        }
    }
    if (Thread.interrupted()) {
        throw new InterruptedException();
    }
}

5. fileProcess () 방법을 실현합니다. 이 방법은 처리 중인 파일과 찾아야 할 파일 이름을 비교합니다.파일 이름이 같으면 콘솔에서 정보를 인쇄합니다.그리고 스레드가 중단되었는지 확인하고, 만약 그렇다면, Interrupted Exception 이상을 던집니다.코드는 다음과 같습니다.

/**
 *
 *
 * @param file
 * @throws InterruptedException
 */
private void fileProcess(File file) throws InterruptedException {
    if (file.getName().equals(fileName)) {
        System.out.printf("%s : %s
",
                Thread.currentThread().getName(),
                file.getAbsolutePath());
    }

    if (Thread.interrupted()) {
        throw new InterruptedException();
    }
}

6. 이제 예시된 메인 클래스를 실현하고main () 방법을 실현합니다.코드는 다음과 같습니다.

public class Main {
    public static void main(String[] args) {
7. FileSearch 객체를 만들고 초기화한 다음 작업을 수행하기 위해 Thread 객체를 만듭니다.그리고 이 라인을 시작합니다.코드는 다음과 같습니다.

FileSearch fileSearch = new FileSearch("C:\\", "autoexec.bat");
Thread thread = new Thread(fileSearch);
thread.start();
8. 10초간 기다렸다가 라인을 끊는다.코드는 다음과 같습니다.

try {
    TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
    e.printStackTrace();
}

thread.interrupt();

9. 이 예시를 실행하고 결과를 보십시오.
그 까닭을 알다
다음은 라인이 실행된 결과입니다.출력에서 알 수 있듯이 FileSearch가 중단된 후에 어떻게 라인 실행을 중단하는지 알 수 있습니다.

Thread-0 : C:\autoexec.bat
Thread-0: The search has been interrupted
이 예에서는 스레드의 중단을 제어하기 위해 Java의 예외를 사용합니다.예시를 실행할 때, 프로그램은 지정한 디렉터리와 하위 디렉터리에 대상 파일이 포함되어 있는지 검사합니다.예를 들어\b\c\d를 입력하면 프로그램은directoryProcess () 방법을 세 번 반복해서 호출합니다.루틴이 중단된 것을 감지하면,Interrupted Exception 이상이 발생합니다. 몇 번의 귀속 호출을 실행하든지 간에, 프로그램은run () 방법을 실행하기 시작합니다.
영원히 끝이 없다
InterruptedException 이상은 일반적으로 Java 병렬 API, 예를 들어 sleep () 방법에 의해 던져집니다.
나래주의
본고는 《Java7 Concurrency Cookbook》(D 오이고에서 《Java7 병발 예시집》으로 번역)에서 번역한 것으로 학습 자료로만 사용된다.권한이 없으면 어떠한 상업 행위에도 사용할 수 없다.
소소하다
FileSearch 클래스의 전체 코드

package com.diguage.books.concurrencycookbook.chapter1.recipe4;

import java.io.File;

/**
 * Date: 2013-09-18
 * Time: 18:21
 */
public class FileSearch implements Runnable {
    private String initPath;
    private String fileName;

    /**
     *
     *
     * @param initPath
     * @param fileName
     */
    public FileSearch(String initPath, String fileName) {
        this.initPath = initPath;
        this.fileName = fileName;
    }

    @Override
    public void run() {
        File file = new File(initPath);
        if (file.isDirectory()) {
            try {
                directoryProcess(file);
            } catch (InterruptedException e) {
                System.out.printf("%s: The search has been interrupted",
                        Thread.currentThread().getName());
            }
        }
    }

    /**
     *
     *
     * @param file
     * @throws InterruptedException
     */
    private void directoryProcess(File file) throws InterruptedException {
        File[] list = file.listFiles();
        if (null != list) {
            for (int i = 0; i < list.length; i++) {
                if (list[i].isDirectory()) {
                    directoryProcess(list[i]);
                } else {
                    fileProcess(list[i]);
                }

            }
        }
        if (Thread.interrupted()) {
            throw new InterruptedException();
        }
    }

    /**
     *
     *
     * @param file
     * @throws InterruptedException
     */
    private void fileProcess(File file) throws InterruptedException {
        if (file.getName().equals(fileName)) {
            System.out.printf("%s : %s
",
                    Thread.currentThread().getName(),
                    file.getAbsolutePath());
        }

        if (Thread.interrupted()) {
            throw new InterruptedException();
        }
    }
}

Main 클래스의 전체 코드

package com.diguage.books.concurrencycookbook.chapter1.recipe4;

import java.util.concurrent.TimeUnit;

/**
 * Date: 2013-09-18
 * Time: 19:28
 */
public class Main {
    public static void main(String[] args) {
        FileSearch fileSearch = new FileSearch("C:\\", "autoexec.bat");
        Thread thread = new Thread(fileSearch);
        thread.start();

        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        thread.interrupt();
    }
}

좋은 웹페이지 즐겨찾기