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");
}
}