Java 동시 프로그래밍 예(10): 스레드 그룹

스레드 그룹화는 Java 병렬 API에서 제공하는 흥미로운 기능입니다.우리는 하나의 라인을 하나의 독립 단원으로 볼 수 있을 뿐만 아니라, 라인 그룹의 라인 대상을 마음대로 조종할 수 있다.예를 들어 같은 작업을 실행하기 위해 하나의 라인을 제어할 수 있으며, 얼마나 많은 라인이 실행 중인지 신경 쓸 필요가 없고, 모든 라인의 실행을 중단하는 호출을 한 번에 중단할 수도 있다.
Java는 스레드 그룹을 제어하기 위해 ThreadGroup 클래스를 제공합니다.하나의 스레드 그룹은 스레드 대상을 통해 만들 수도 있고, 다른 스레드 그룹으로 만들 수도 있으며, 트리 구조의 스레드를 생성할 수도 있다.
Effective Java의 지침에 따라 ThreadGroup 사용을 권장하지 않습니다.Executor를 사용하는 것이 좋습니다.
D과고는 특별히 이렇게 설명했다.
이 절에서, 우리는 간단한 예시를 개발하기 위해ThreadGroup을 사용합니다.우리는 휴면 시간이 같지 않은 10개의 라인 (예를 들어 아날로그 검색) 을 만들 것입니다. 그 중 하나가 완성되면 나머지 라인을 중단합니다.
그 사실을 알다
아래와 같은 절차에 따라 예시 코드를 완성하세요.
1. 첫 번째 작업을 완료한 스레드의 이름을 저장하기 위한 Result라는 클래스를 만듭니다.String 형식의 개인 변수,name를 설명하고 Setter/Getter 방법을 생성합니다.코드는 다음과 같습니다.

public class Result {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2. SearchTask라는 클래스를 만들고 Runnable 인터페이스를 실현합니다.코드는 다음과 같습니다.

public class SearchTask implements Runnable {
3. Result 형식의 개인 변수를 설명하고 구조 함수를 통해 이 변수를 실례화합니다.코드는 다음과 같습니다.

private Result result;

public SearchTask(Result result) {
    this.result = result;
}

4. run () 방법을 실현하고 그 중에서doTask () 방법을 호출하여 완성되거나 중단될 때까지 기다립니다.이 방법은 컨트롤러에 정보를 출력해서 라인의 시작, 끝, 중단을 표시합니다.코드는 다음과 같습니다.

@Override
public void run() {
    String name = Thread.currentThread().getName();
    System.out.printf("Thread %s: Start
", name);
    try {
        doTask();
        result.setName(name);
    } catch (InterruptedException e) {
        System.out.printf("Thread %s: Interrupted
", name);
        return;
    }
    System.out.printf("Thread %s: End
", name);
}
5. DoTask () 방법을 실현합니다. 이 방법은 Random 대상을 만들고 이 대상을 사용하여 랜덤 수를 생성하여 라인의 휴면 시간을 조절합니다.코드는 다음과 같습니다.

//
private void doTask() throws InterruptedException {
    Random random = new Random(new Date().getTime());
    int value = (int) (random.nextDouble() * 100);
    System.out.printf("Thread %s: %d
",
            Thread.currentThread().getName(), value);
    TimeUnit.SECONDS.sleep(value);
}
6. 예시 프로그램의 메인 클래스, Main을 만들고main () 방법을 실현합니다.코드는 다음과 같습니다.

public class Main {
    public static void main(String[] args) {
7. Searcher라는 ThreadGroup 객체를 만듭니다.코드는 다음과 같습니다.

ThreadGroup threadGroup = new ThreadGroup("Searcher");
8. 그런 다음 Result 객체 및 SearchTask 객체를 만듭니다.코드는 다음과 같습니다.

Result result = new Result();
SearchTask searchTask = new SearchTask(result);
9.SearchTask 대상은 10개의 Thread 대상을 만들고 Thread 대상을 만들 때 ThreadGroup 대상을 첫 번째 매개 변수로 사용하여 Thread 클래스의 구조 함수에 전달합니다.코드는 다음과 같습니다.

for (int i = 0; i < 5; i++) {
    Thread thread = new Thread(threadGroup, searchTask);
    thread.start();
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
10. list() 방법을 사용하여 ThreadGroup 객체의 정보를 인쇄합니다.코드는 다음과 같습니다.

System.out.printf("Number of Threads: %d
", threadGroup.activeCount());
System.out.println("Information about the Thread Group");
threadGroup.list();
11. activeCount () 와 enumerate () 를 사용하여ThreadGroup 대상의 활성 스레드 수를 가져와 한 스레드 그룹에 복사합니다.get*() 방법을 사용하여 스레드의 이름과 상태를 가져옵니다.코드는 다음과 같습니다.

Thread[] threads = new Thread[threadGroup.activeCount()];
threadGroup.enumerate(threads);
for (int i = 0; i < threadGroup.activeCount(); i++) {
    System.out.printf("Thread %s: %s
", threads[i].getName(),
            threads[i].getState());
}
12. WaitFinish () 방법을 호출하여ThreadGroup 대상 중 한 라인이 작업을 완료할 때까지 기다립니다.잠시 후 이 방법을 실현합니다.코드는 다음과 같습니다.

waitFinish(threadGroup);
13. 인터럽트 () 방법을 사용하여 라인 그룹의 다른 라인을 중단합니다.코드는 다음과 같습니다.

threadGroup.interrupt();
14. waitFinish() 방법을 실현하고 activeCount() 방법으로 라인의 실행 결과를 제어합니다.코드는 다음과 같습니다.

//
private static void waitFinish(ThreadGroup threadGroup) {
    while (threadGroup.activeCount() > 9) {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
15. 프로그램을 실행하여 실행 효과를 봅니다.
그 까닭을 알다
다음은 프로그램이 실행한 결과입니다.list () 방법의 출력, 각 라인의 상태 등을 볼 수 있습니다.

Thread Thread-0: Start
Thread Thread-0: 52
Thread Thread-1: Start
Thread Thread-1: 41
Thread Thread-2: Start
Thread Thread-2: 69
Thread Thread-3: Start
Thread Thread-3: 60
Thread Thread-4: Start
Thread Thread-4: 88
Number of Threads: 5
Information about the Thread Group
java.lang.ThreadGroup[name=Searcher,maxpri=10]
    Thread[Thread-0,5,Searcher]
    Thread[Thread-1,5,Searcher]
    Thread[Thread-2,5,Searcher]
    Thread[Thread-3,5,Searcher]
    Thread[Thread-4,5,Searcher]
Thread Thread-0: TIMED_WAITING
Thread Thread-1: TIMED_WAITING
Thread Thread-2: TIMED_WAITING
Thread Thread-3: TIMED_WAITING
Thread Thread-4: TIMED_WAITING
Thread Thread-1: Interrupted
Thread Thread-4: Interrupted
Thread Thread-2: Interrupted
Thread Thread-0: Interrupted
Thread Thread-3: Interrupted
ThreadGroup 클래스는 많은 Thread 객체와 관련된 ThreadGroup 객체를 저장합니다.이 종류의 방법을 호출하여 라인의 정보에 접근할 수 있고 중단과 같은 각종 조작을 할 수 있다.
영원히 끝이 없다
Thread Group 클래스에는 여러 가지 방법이 있습니다.API 문서를 검토하여 전체 메소드 설명을 확인하십시오.
나래주의
본고는 《Java7 Concurrency Cookbook》(D 오이고에서 《Java7 병발 예시집》으로 번역)에서 번역한 것으로 학습 자료로만 사용된다.권한이 없으면 어떠한 상업 행위에도 사용할 수 없다.
소소하다
다음은 이 절의 예시에 사용된 코드의 전체 버전이다.
Result 클래스의 전체 코드:

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

/**
 *
 * Date: 2013-09-30
 * Time: 00:45
 */
public class Result {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

SearchTask 클래스의 전체 코드

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

import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 *
 * Date: 2013-10-02
 * Time: 22:38
 */
public class SearchTask implements Runnable {
    private Result result;

    public SearchTask(Result result) {
        this.result = result;
    }

    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        System.out.printf("Thread %s: Start
", name);
        try {
            doTask();
            result.setName(name);
        } catch (InterruptedException e) {
            System.out.printf("Thread %s: Interrupted
", name);
            return;
        }
        System.out.printf("Thread %s: End
", name);
    }

    //
    private void doTask() throws InterruptedException {
        Random random = new Random(new Date().getTime());
        int value = (int) (random.nextDouble() * 100);
        System.out.printf("Thread %s: %d
",
                Thread.currentThread().getName(), value);
        TimeUnit.SECONDS.sleep(value);
    }
}

Main 클래스의 전체 코드:

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

import java.util.concurrent.TimeUnit;

/**
 *
 * Date: 2013-10-02
 * Time: 22:45
 */
public class Main {
    public static void main(String[] args) {
        ThreadGroup threadGroup = new ThreadGroup("Searcher");

        Result result = new Result();
        SearchTask searchTask = new SearchTask(result);

        for (int i = 0; i < 5; i++) {
            Thread thread = new Thread(threadGroup, searchTask);
            thread.start();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.printf("Number of Threads: %d
", threadGroup.activeCount());
        System.out.println("Information about the Thread Group");
        threadGroup.list();

        Thread[] threads = new Thread[threadGroup.activeCount()];
        threadGroup.enumerate(threads);
        for (int i = 0; i < threadGroup.activeCount(); i++) {
            System.out.printf("Thread %s: %s
", threads[i].getName(),
                    threads[i].getState());
        }

        waitFinish(threadGroup);

        threadGroup.interrupt();
    }

    //
    private static void waitFinish(ThreadGroup threadGroup) {
        while (threadGroup.activeCount() > 9) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

좋은 웹페이지 즐겨찾기