Java并发编程示例(二):获取和设置线程信息

来源:互联网 发布:淘宝剑三高洁丝 编辑:程序博客网 时间:2024/06/05 05:13

开门见山

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: Status of Thread 0 : NEW
Main: Status of Thread 1 : NEW
Main: Status of Thread 2 : NEW
Main: Status of Thread 3 : NEW
Main: Status of Thread 4 : NEW
Main: Status of Thread 5 : NEW
Main: Status of Thread 6 : NEW
Main: Status of Thread 7 : NEW
Main: Status of Thread 8 : NEW
Main: Status of Thread 9 : NEW
Main : Id 10 = Thread-0
Main : Priority: 10
Main : Old State: NEW
Main : New State: RUNNABLE
Main : **********************
Main : Id 11 = Thread-1
Main : Priority: 1
Main : Old State: NEW
Main : New State: BLOCKED
Main : **********************
Main : Id 12 = Thread-2
Main : Priority: 10
Main : Old State: NEW
Main : New State: BLOCKED
Main : **********************
Main : Id 13 = Thread-3
Main : Priority: 1
Main : Old State: NEW
Main : New State: BLOCKED
Main : **********************
Main : Id 14 = Thread-4
Main : Priority: 10
Main : Old State: NEW
Main : New State: BLOCKED
Main : **********************
Main : Id 15 = Thread-5
Main : Priority: 1
Main : Old State: NEW
Main : New State: BLOCKED
Main : **********************
Main : Id 16 = Thread-6
Main : Priority: 10
Main : Old State: NEW
Main : New State: BLOCKED
Main : **********************
Main : Id 17 = Thread-7
Main : Priority: 1
Main : Old State: NEW
Main : New State: BLOCKED
Main : **********************
Main : Id 18 = Thread-8
Main : Priority: 10
Main : Old State: NEW
Main : New State: BLOCKED
Main : **********************
Main : Id 19 = Thread-9
Main : Priority: 1
Main : Old State: NEW
Main : New State: RUNNABLE
Main : **********************
Main : Id 10 = Thread-0
Main : Priority: 10
Main : Old State: RUNNABLE
Main : New State: TERMINATED
Main : **********************
Main : Id 17 = Thread-7
Main : Priority: 1
Main : Old State: BLOCKED
Main : New State: RUNNABLE
Main : **********************
Main : Id 19 = Thread-9
Main : Priority: 1
Main : Old State: RUNNABLE
Main : New State: BLOCKED
Main : **********************
Main : Id 17 = Thread-7
Main : Priority: 1
Main : Old State: RUNNABLE
Main : New State: TERMINATED
Main : **********************
Main : Id 15 = Thread-5
Main : Priority: 1
Main : Old State: BLOCKED
Main : New State: RUNNABLE
Main : **********************
Main : Id 15 = Thread-5
Main : Priority: 1
Main : Old State: RUNNABLE
Main : New State: TERMINATED
Main : **********************
Main : Id 13 = Thread-3
Main : Priority: 1
Main : Old State: BLOCKED
Main : New State: RUNNABLE
Main : **********************
Main : Id 13 = Thread-3
Main : Priority: 1
Main : Old State: RUNNABLE
Main : New State: TERMINATED
Main : **********************
Main : Id 18 = Thread-8
Main : Priority: 10
Main : Old State: BLOCKED
Main : New State: RUNNABLE
Main : **********************
Main : Id 16 = Thread-6
Main : Priority: 10
Main : Old State: BLOCKED
Main : New State: BLOCKED
Main : **********************
Main : Id 14 = Thread-4
Main : Priority: 10
Main : Old State: BLOCKED
Main : New State: BLOCKED
Main : **********************
Main : Id 12 = Thread-2
Main : Priority: 10
Main : Old State: BLOCKED
Main : New State: BLOCKED
Main : **********************
Main : Id 16 = Thread-6
Main : Priority: 10
Main : Old State: BLOCKED
Main : New State: BLOCKED
Main : **********************
Main : Id 18 = Thread-8
Main : Priority: 10
Main : Old State: BLOCKED
Main : New State: RUNNABLE
Main : **********************
Main : Id 18 = Thread-8
Main : Priority: 10
Main : Old State: RUNNABLE
Main : New State: TERMINATED
Main : **********************
Main : Id 11 = Thread-1
Main : Priority: 1
Main : Old State: BLOCKED
Main : New State: RUNNABLE
Main : **********************
Main : Id 11 = Thread-1
Main : Priority: 1
Main : Old State: RUNNABLE
Main : New State: TERMINATED
Main : **********************
Main : Id 19 = Thread-9
Main : Priority: 1
Main : Old State: BLOCKED
Main : New State: RUNNABLE
Main : **********************
Main : Id 16 = Thread-6
Main : Priority: 10
Main : Old State: BLOCKED
Main : New State: RUNNABLE
Main : **********************
Main : Id 19 = Thread-9
Main : Priority: 1
Main : Old State: RUNNABLE
Main : New State: BLOCKED
Main : **********************
Main : Id 16 = Thread-6
Main : Priority: 10
Main : Old State: RUNNABLE
Main : New State: TERMINATED
Main : **********************
Main : Id 19 = Thread-9
Main : Priority: 1
Main : Old State: BLOCKED
Main : New State: RUNNABLE
Main : **********************
Main : Id 14 = Thread-4
Main : Priority: 10
Main : Old State: BLOCKED
Main : New State: RUNNABLE
Main : **********************
Main : Id 19 = Thread-9
Main : Priority: 1
Main : Old State: RUNNABLE
Main : New State: BLOCKED
Main : **********************
Main : Id 14 = Thread-4
Main : Priority: 10
Main : Old State: RUNNABLE
Main : New State: TERMINATED
Main : **********************
Main : Id 19 = Thread-9
Main : Priority: 1
Main : Old State: BLOCKED
Main : New State: RUNNABLE
Main : **********************
Main : Id 12 = Thread-2
Main : Priority: 10
Main : Old State: BLOCKED
Main : New State: RUNNABLE
Main : **********************
Main : Id 12 = Thread-2
Main : Priority: 10
Main : Old State: RUNNABLE
Main : New State: TERMINATED
Main : **********************
Main : Id 19 = Thread-9
Main : Priority: 1
Main : Old State: RUNNABLE
Main : New State: TERMINATED
Main : **********************
下面是控制台的输出片段。输出的是每个线程计算的乘法表,以及所有的线程计算过程。同时,从这里可以更细粒度地看到每个线程的演化过程。

Thread-0: 0 * 0 = 0
Thread-0: 0 * 1 = 0
Thread-0: 0 * 2 = 0
Thread-0: 0 * 3 = 0
Thread-0: 0 * 4 = 0
Thread-0: 0 * 5 = 0
Thread-0: 0 * 6 = 0
Thread-0: 0 * 7 = 0
Thread-0: 0 * 8 = 0
Thread-0: 0 * 9 = 0
Thread-9: 9 * 0 = 0
Thread-9: 9 * 1 = 9
Thread-9: 9 * 2 = 18
Thread-9: 9 * 3 = 27
Thread-9: 9 * 4 = 36
Thread-9: 9 * 5 = 45
Thread-9: 9 * 6 = 54
Thread-7: 7 * 0 = 0
Thread-7: 7 * 1 = 7
Thread-7: 7 * 2 = 14
Thread-7: 7 * 3 = 21
Thread-7: 7 * 4 = 28
Thread-7: 7 * 5 = 35
Thread-7: 7 * 6 = 42
Thread-7: 7 * 7 = 49
Thread-7: 7 * 8 = 56
Thread-7: 7 * 9 = 63
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-5: 5 * 5 = 25
Thread-5: 5 * 6 = 30
Thread-5: 5 * 7 = 35
Thread-5: 5 * 8 = 40
Thread-5: 5 * 9 = 45
Thread-3: 3 * 0 = 0
Thread-3: 3 * 1 = 3
Thread-3: 3 * 2 = 6
Thread-3: 3 * 3 = 9
Thread-3: 3 * 4 = 12
Thread-3: 3 * 5 = 15
Thread-3: 3 * 6 = 18
Thread-3: 3 * 7 = 21
Thread-3: 3 * 8 = 24
Thread-3: 3 * 9 = 27
Thread-1: 1 * 0 = 0
Thread-8: 8 * 0 = 0
Thread-6: 6 * 0 = 0
Thread-4: 4 * 0 = 0
Thread-2: 2 * 0 = 0
Thread-4: 4 * 1 = 4
Thread-6: 6 * 1 = 6
Thread-8: 8 * 1 = 8
Thread-8: 8 * 2 = 16
Thread-8: 8 * 3 = 24
Thread-8: 8 * 4 = 32
Thread-8: 8 * 5 = 40
Thread-8: 8 * 6 = 48
Thread-8: 8 * 7 = 56
Thread-8: 8 * 8 = 64
Thread-8: 8 * 9 = 72
Thread-1: 1 * 1 = 1
Thread-1: 1 * 2 = 2
Thread-1: 1 * 3 = 3
Thread-1: 1 * 4 = 4
Thread-1: 1 * 5 = 5
Thread-1: 1 * 6 = 6
Thread-1: 1 * 7 = 7
Thread-1: 1 * 8 = 8
Thread-1: 1 * 9 = 9
Thread-9: 9 * 7 = 63
Thread-6: 6 * 2 = 12
Thread-4: 4 * 2 = 8
Thread-2: 2 * 1 = 2
Thread-4: 4 * 3 = 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-9: 9 * 8 = 72
Thread-4: 4 * 4 = 16
Thread-2: 2 * 2 = 4
Thread-4: 4 * 5 = 20
Thread-4: 4 * 6 = 24
Thread-4: 4 * 7 = 28
Thread-4: 4 * 8 = 32
Thread-4: 4 * 9 = 36
Thread-9: 9 * 9 = 81
Thread-2: 2 * 3 = 6
Thread-2: 2 * 4 = 8
Thread-2: 2 * 5 = 10
Thread-2: 2 * 6 = 12
Thread-2: 2 * 7 = 14
Thread-2: 2 * 8 = 16
Thread-2: 2 * 9 = 18
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类的完整代码

public class Calculator implements Runnable {
private int number;

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

}

Test类的完整代码

package com.ysk.demo2;

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

public class Test {
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.线程一共分为以下状态:新建,运行,阻塞,等待,限时等待,终止等6个状态。
2.每个线程有唯一ID,通过getState()方法可以获取线程运行状态,getName()获取线程名称,setPriority()设置线程优先级,默认为5,范围为(1-10)。
3.线程优先级并不能决定哪个线程先执行,只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 下眼底有小白点怎么办 狗的白眼球充血怎么办 眼球有出血点是怎么办 吃阿胶上火了该怎么办 胎儿胼胝体发育不良怎么办 鸡眼看到硬芯了怎么办 小脚趾起茧子疼怎么办 脚起老茧很痛怎么办 化疗后骨髓抑制严重怎么办 胃炎引起的胃胀怎么办 胃病胀肚子很鼓怎么办 小孩淋巴结发炎肚子疼痛怎么办 顺产后子宫脱垂怎么办 顺产完子宫脱垂怎么办 额头长了个鱼鳞怎么办 脸上长了很多痣怎么办 做过狐臭的疤痕怎么办 痤疮留下的红印怎么办 脸上疤掉了黑印怎么办 脸上有黑色的疤怎么办 一只眼睛外斜视怎么办 残币银行不给换怎么办 手上有多套房的怎么办 长了两层脚指甲怎么办 指甲长了两层怎么办 脚趾甲长了两层怎么办 产妇气血虚没奶怎么办 哺乳期气血不足奶水少怎么办 刚怀孕喝了啤酒怎么办 受风怎么办最快最有效 孕妇后背受风了怎么办 肩膀和后背受风怎么办 手指关节杵肿了怎么办 骨关节退行性变怎么办 疼风脚趾肿了怎么办 痛风脚右侧肿了怎么办 痛风引起的脚肿怎么办 老人腰闪了该怎么办 腰闪了站不起来怎么办 又怕冷又爱上火怎么办 肝上多发小囊肿怎么办