程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java並發編程示例(二):獲得和設置線程信息

Java並發編程示例(二):獲得和設置線程信息

編輯:關於JAVA

Java並發編程示例(二):獲得和設置線程信息。本站提示廣大學習愛好者:(Java並發編程示例(二):獲得和設置線程信息)文章只能為提供參考,不一定能成為您想要的結果。以下是Java並發編程示例(二):獲得和設置線程信息正文


Thread類包括幾個屬性,這些屬性所表現的信息能贊助我們辨認線程、不雅察其狀況、掌握其優先級等。這些線程包含以下幾種:

ID: 該屬性表現每一個線程的獨一標識;
Name: 該屬性存儲每一個線程的稱號;
Priority: 該屬性存儲每一個Thread對象的優先級。線程優先級分1到10十個級別,1表現最低優先級,10表現最高優先級。其實不推舉修正線程的優先級,然則假如確切有這方面的需求,也能夠測驗考試一下。
Status: 該屬性存儲線程的狀況。線程共有六種分歧的狀況:新建(new)、運轉(runnable)、壅塞(blocked)、期待(waiting)、限時期待(time waiting)或許終止(terminated)。線程的狀況一定是個中一種。

在本末節,我們將開辟一個法式,法式中新建十個線程,而且設定每一個線程的稱號和優先級。然後履行線程,不雅察線程的狀況信息,直到線程履行停止。再解釋一點,這些線程照樣盤算一個數的乘法表。

知其然

依照上面所示步調,來完成該示例:

1.創立一個名為 Calculator的類,完成Runnable接口。代碼以下:

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\n",
                Thread.currentThread().getName(),
                number, i, i * number);
    }
}

4.如今,我們來完成示例運用的主類(main class)。創立名為Main的類,在該類中添加main辦法。代碼以下:

public class Main {
    public static void main(String[] args) {

5.創立兩個包括十個元素數組,一個是Thread類型的,一個是Thread.State類型,然後全體初始化。這兩個數組,一個用於存儲我們將以履行的線程,別的一個存儲這些線程的狀況。代碼以下:


Thread[] threads = new Thread[10];
Thread.State[] status = new Thread.State[threads.length];

6.創立十個Calculator對象,而且應用分歧的數來初始化每一個對象。應用這些Calculator對象創立十個Thread對象,存儲到下面的創立數組中。同時,設置這些線程的優先級,五個設置成最高優先級;五個設置成最低優先級。代碼以下:

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進級到第七版,把編譯對象設置成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\n", thread.getId(), thread.getName());
    pw.printf("Main : Priority: %d\n", thread.getPriority());
    pw.printf("Main : Old State: %s\n", state);
    pw.printf("Main : New State: %s\n", thread.getState());
    pw.printf("Main : ********************************\n");
}

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的異常,

拿來主義

本文是從 《Java 7 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\n",
                    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\n",
                    thread.getId(), thread.getName());
        pw.printf("Main : Priority: %d\n", thread.getPriority());
        pw.printf("Main : Old State: %s\n", state);
        pw.printf("Main : New State: %s\n", thread.getState());
        pw.printf("Main : ********************************\n");
    }
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved