Java 동시 프로그래밍 예(二): 스레드 정보 가져오기 및 설정

Thread 클래스는 몇 가지 속성을 포함하는데 이 속성이 표시하는 정보는 우리가 라인을 식별하고 상태를 관찰하며 우선순위를 제어하는 데 도움을 줄 수 있다.이러한 스레드는 다음과 같은 몇 가지로 구성됩니다.
ID: 이 속성은 각 스레드의 고유 ID를 나타냅니다.
Name: 이 속성은 각 스레드의 이름을 저장합니다.
Priority: 이 속성은 각 Thread 객체의 우선 순위를 저장합니다.스레드 우선 순위는 1부터 110개 단계로 나뉘는데 1은 최저 우선 순위, 10은 최고 우선 순위를 나타낸다.라인을 수정하는 우선순위는 추천하지 않지만, 이 방면의 수요가 있다면 시도해 볼 수도 있다.
Status: 이 속성은 스레드의 상태를 저장합니다.새 (new), 실행 (runnable), 차단 (blocked), 대기 (waiting), 시간 제한 대기 (time waiting) 또는 종료 (terminated) 등 6가지 다른 상태가 있습니다.라인의 상태는 반드시 그 중의 하나이다.
이 소절에서, 우리는 프로그램에 10개의 라인을 새로 만들고, 모든 라인의 이름과 우선순위를 설정하는 프로그램을 개발할 것이다.그리고 라인을 실행하고 라인의 상태 정보를 관찰하며 라인의 실행이 끝날 때까지 합니다.다시 한 번 설명하자면, 이 노선들은 여전히 하나의 수를 계산하는 곱셈표이다.
그 사실을 알다
다음 절차에 따라 이 예제를 수행합니다.
1. Runnable 인터페이스를 실현하기 위해 Calculator라는 클래스를 만듭니다.코드는 다음과 같습니다.

public class Calculator implements Runnable {
2. 개인 성형 속성을 성명합니다. 이름은number이고 이 유형의 구조 함수를 실현하여 방금 성명한 속성을 초기화합니다.코드는 다음과 같습니다.

private int number;

public Calculator(int number) {
    this.number = number;
}

3. run () 방법을 실현합니다. 이 방법은 우리가 만든 루틴이 실행될 때 실행되는 프로그램 (instruction) 이기 때문에 이 방법은 곱셈표를 계산하는 데 사용됩니다.구체적인 코드는 다음과 같습니다.

@Override
public void run() {
    for (int i = 0; i < 10; i++) {
        System.out.printf("%s: %d * %d = %d
",
                Thread.currentThread().getName(),
                number, i, i * number);
    }
}
4. 이제 예시 응용의 메인 클래스(main class)를 실현합니다.ain이라는 클래스를 만들고 이 클래스에main 방법을 추가합니다.코드는 다음과 같습니다.

public class Main {
    public static void main(String[] args) {
5. 10개의 원소를 포함하는 두 개의 그룹을 만듭니다. 하나는 Thread 형식이고 하나는 Thread입니다.State 유형을 모두 초기화합니다.이 두 개의 수조는 우리가 실행할 라인을 저장하는 데 사용되고, 다른 하나는 이 라인을 저장하는 상태에 사용된다.코드는 다음과 같습니다.

Thread[] threads = new Thread[10];
Thread.State[] status = new Thread.State[threads.length];
6. 10개의 Calculator 객체를 만들고 각 객체를 초기화하기 위해 서로 다른 수를 사용합니다.이 Calculator 객체를 사용하여 10개의 Thread 객체를 만들고 위의 생성 그룹에 저장합니다.동시에 이 라인의 우선순위를 설정하고 다섯 개를 최고 우선순위로 설정한다.5개를 최소 우선 순위로 설정합니다.코드는 다음과 같습니다.

for (int i = 0; i < threads.length; i++) {
    threads[i] = new Thread(new Calculator(i));
    if ((i % 2) == 0) {
        threads[i].setPriority(Thread.MAX_PRIORITY);
    } else {
        threads[i].setPriority(Thread.MIN_PRIORITY);
    }
    threads[i].setName("Thread-" + i);
}
7. 라인 상태의 변환을 파일에 기록하는 PrintWriter 객체를 만듭니다.코드는 다음과 같습니다.

try (FileWriter file = new FileWriter("D:\\thread.log");
     PrintWriter pw = new PrintWriter(file)) {
여기에는 Java7 구문이 사용되므로 JDK를 7 버전으로 업그레이드하고 컴파일 도구를 Java7로 설정하십시오.그렇지 않으면 문법 오류가 보고됩니다.
8. 모든 스레드의 상태를 파일에 기록합니다.현재 상태는 새로 만들기(NEW)일 것입니다.코드는 다음과 같습니다.

for (int i = 0; i < threads.length; i++) {
    Thread thread = threads[i];
    pw.println("Main: Status of Thread " + i +
            " : " + threads[i].getState());
    status[i] = threads[i].getState();
}
9. 모든 라인을 시작합니다.코드 입력:

for (int i = 0; i < threads.length; i++) {
    threads[i].start();
}
10. 다른 한편, 우리는 라인 실행이 끝날 때까지 라인을 감시하고 있다.만약 우리가 스레드의 상태가 바뀌었다는 것을 발견하면, 즉시 스레드 상태를 파일에 기록합니다.코드는 다음과 같습니다.

boolean finish = false;

while (!finish) {
    for (int i = 0; i < threads.length; i++) {
        if (threads[i].getState() != status[i]) {
            writeThreadInfo(pw, threads[i], status[i]);
            status[i] = threads[i].getState();
        }
    }
    finish = true;
    for (int i = 0; i < threads.length; i++) {
        finish = finish
                && (threads[i].getState() == Thread.State.TERMINATED);
    }
}

11. writeThreadInfo 방법을 실현합니다. 이 방법은 스레드의 ID, 이름, 우선순위, 낡은 상태, 새로운 상태를 파일에 기록합니다.코드는 다음과 같습니다.

/**
 * 。
 *
 * @param pw     PrintWriter
 * @param thread
 * @param state 
 */
private static void writeThreadInfo(PrintWriter pw,
                                  Thread thread, Thread.State state) {
    pw.printf("Main : Id %d = %s
", thread.getId(), thread.getName());
    pw.printf("Main : Priority: %d
", thread.getPriority());
    pw.printf("Main : Old State: %s
", state);
    pw.printf("Main : New State: %s
", thread.getState());
    pw.printf("Main : ********************************
");
}
12. 이 예시를 실행하고thread를 엽니다.log 파일, 모든 라인의 진화 과정을 보십시오.
그 까닭을 알다
다음은 thread입니다.log 파일의 내용 세션입니다.파일 내용을 보면 높은 우선순위의 라인이 낮은 우선순위의 라인보다 대체적으로 실행을 빨리 끝낸다는 것을 알 수 있다.또한 각 라인의 상태 진화 과정도 볼 수 있다.

Main : ********************************
Main : Id 11 = Thread-2
Main : Priority: 10
Main : Old State: BLOCKED
Main : New State: TERMINATED
Main : ********************************
Main : Id 13 = Thread-4
Main : Priority: 10
Main : Old State: BLOCKED
Main : New State: TERMINATED
Main : ********************************
Main : Id 14 = Thread-5
Main : Priority: 1
Main : Old State: BLOCKED
Main : New State: TERMINATED
Main : ********************************
다음은 컨트롤러의 출력 부분입니다.출력된 것은 모든 스레드 계산의 곱셈표와 모든 스레드 계산 과정이다.동시에 여기서 각 라인의 진화 과정을 더욱 세밀하게 볼 수 있다.

Thread-8: 8 * 2 = 16
Thread-8: 8 * 3 = 24
Thread-8: 8 * 4 = 32
Thread-6: 6 * 0 = 0
Thread-6: 6 * 1 = 6
Thread-6: 6 * 2 = 12
Thread-6: 6 * 3 = 18
Thread-6: 6 * 4 = 24
Thread-6: 6 * 5 = 30
Thread-6: 6 * 6 = 36
Thread-6: 6 * 7 = 42
Thread-6: 6 * 8 = 48
Thread-6: 6 * 9 = 54
Thread-5: 5 * 0 = 0
Thread-5: 5 * 1 = 5
Thread-5: 5 * 2 = 10
Thread-5: 5 * 3 = 15
Thread-5: 5 * 4 = 20
Thread 클래스에는 스레드 정보를 저장하는 데 필요한 모든 속성이 있습니다.Java 가상 머신은 스레드 우선 순위를 사용하여 CPU를 사용할 때마다 하나의 스레드를 스케줄링하고 스레드의 상황에 따라 각 스레드의 상태를 설정합니다.
스레드의 이름을 설정하지 않으면 Java 가상 기회에서 이 형식을 사용할 때 이름을 지정합니다. thread-XX입니다. 그 중에서 XX는 숫자입니다.우리는 스레드의 ID와 스레드의 상태를 수정할 수 없습니다.Thread 클래스도 이러한 수정을 허용하기 위해 setId () 와 setStatus () 방법을 실현하지 않았습니다.
영원히 끝이 없다
이 섹션에서는 스레드 정보에 액세스하기 위해 Thread 객체를 사용하는 방법을 학습했습니다.사실, Runnable의 실현 클래스도 우리가 이 정보에 접근하는 것을 실행한다.Thread 클래스의 정적 방법currentThread () 는 실행 중인 Runnable 구현 클래스의 대상을 가져와 라인에 접근할 수 있습니다.
주의해야 할 것은 1 ~ 10 이외의 우선순위를 설정하려고 하면 setPriority () 에서 IllegalArgumentException 이라는 예외가 발생합니다.
나래주의
본고는 《Java7 Concurrency Cookbook》(D 오이고에서 《Java7 병발 예시집》으로 번역)에서 번역한 것으로 학습 자료로만 사용된다.권한이 없으면 어떠한 상업 행위에도 사용할 수 없다.
소소하다
Calculator 클래스의 전체 코드

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

/**
 * Date: 2013-09-13
 * Time: 19:49
 */
public class Calculator implements Runnable {
    private int number;

    public Calculator(int number) {
        this.number = number;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.printf("%s: %d * %d = %d
",
                    Thread.currentThread().getName(),
                    number, i, i * number);
        }
    }
}

Main 클래스의 전체 코드

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

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Date: 2013-09-13
 * Time: 19:51
 */
public class Main {
    public static void main(String[] args) {
        Thread[] threads = new Thread[10];
        Thread.State[] status = new Thread.State[threads.length];

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new Calculator(i));
            if ((i % 2) == 0) {
                threads[i].setPriority(Thread.MAX_PRIORITY);
            } else {
                threads[i].setPriority(Thread.MIN_PRIORITY);
            }
            threads[i].setName("Thread-" + i);
        }

        try (FileWriter file = new FileWriter("D:\\thread.log");
             PrintWriter pw = new PrintWriter(file)) {
            for (int i = 0; i < threads.length; i++) {
                Thread thread = threads[i];
                pw.println("Main: Status of Thread " + i +
                        " : " + threads[i].getState());
                status[i] = threads[i].getState();
            }

            for (int i = 0; i < threads.length; i++) {
                threads[i].start();
            }

            boolean finish = false;

            while (!finish) {
                for (int i = 0; i < threads.length; i++) {
                    if (threads[i].getState() != status[i]) {
                        writeThreadInfo(pw, threads[i], status[i]);
                        status[i] = threads[i].getState();
                    }
                }
                finish = true;
                for (int i = 0; i < threads.length; i++) {
                    finish = finish
                            && (threads[i].getState() == Thread.State.TERMINATED);
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 。
     *
     * @param pw     PrintWriter
     * @param thread
     * @param state 
     */
    private static void writeThreadInfo(PrintWriter pw,
                                      Thread thread, Thread.State state) {
        pw.printf("Main : Id %d = %s
",
                    thread.getId(), thread.getName());
        pw.printf("Main : Priority: %d
", thread.getPriority());
        pw.printf("Main : Old State: %s
", state);
        pw.printf("Main : New State: %s
", thread.getState());
        pw.printf("Main : ********************************
");
    }
}

좋은 웹페이지 즐겨찾기