Java多线程基础 - 线程相关信息的操作

在更深入地学习Java多线程之前,我们必须熟练有关Thread类的某些获取或设置线程相关信息的方法才行。

有关线程的信息,对于我们日常开发比较重要的也就那几个。线程名、线程ID、线程的优先级、线程的状态。这里就以一个简单的程序打印线程的各种信息。

首先,先来看任务类Task的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Task implements Runnable {
private long duration = 0L;

public Task() { }

public Task(long duration) {
this.duration = duration;
}

@Override
public void run() {
long begin = System.currentTimeMillis();
while (System.currentTimeMillis() - begin <= duration) { }
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

这里,我给任务类Task指定了一个域duration存储一个毫秒数,它表示执行该任务的所需时间,默认值是0,但这里也可以通过构造函数指定duration具体的毫秒数是多少。在run方法里,使用一个循环模拟任务的执行,经过duration毫秒后,该循环就会终止。然后,再让执行该任务的线程睡眠200毫秒。任务执行的整个过程如上所述。

而打印线程相关信息的程序代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public class MainThread2 {
private static final int SIZE = 10;
private static Formatter f = new Formatter(System.out);

public static void main(String[] args) {
// 1.创建一个可以容纳10个线程对象的数组
Thread[] threads = new Thread[SIZE];
// 2. 初始化(设置线程的优先级以及线程名)
for (int i = 0; i < SIZE; i++) {
threads[i] = new Thread(new Task(2000));
if (i % 2 == 0)
threads[i].setPriority(Thread.MAX_PRIORITY);
else
threads[i].setPriority(Thread.MIN_PRIORITY);
if (i == 7)
threads[i].setPriority(Thread.NORM_PRIORITY);
if (i % 3 == 0)
threads[i].setName("Thread#" + i);
}

// 3.创建一个保存线程数组中每个线程对应的线程状态
Thread.State[] prevStates = new Thread.State[SIZE];
for (int i = 0; i < SIZE; i++) {
prevStates[i] = threads[i].getState();
}

// 4.启动所有线程
for (int i = 0; i < SIZE; i++)
threads[i].start();

printTitle();

// 5.循环检测所有线程是否运行完毕
boolean isFinish = false;
while (!isFinish) {
for (int i = 0; i < SIZE; i++) {
if (threads[i].getState() != prevStates[i]) {
printThreadInfo("main", threads[i], prevStates[i]);
prevStates[i] = threads[i].getState();
}
}
isFinish = true;
for (int i = 0; i < SIZE; i++) {
isFinish = isFinish && (threads[i].getState() == Thread.State.TERMINATED);
}
}
}

public static void printTitle() {
f.format("%-10s %-12s %-3s %-8s %-13s %-14s\n",
"method", "name", "id", "priority", "current state", "previous state");
f.format("%-10s %-12s %-3s %-8s %-13s %-14s\n",
"------", "----", "--", "--------", "-------------", "--------------");
}

public static void printThreadInfo(String method, Thread thread, Thread.State prevState) {
f.format("%-10s %-12s %-3d %-8d %-13s %-14s\n", method, thread.getName(),
thread.getId(), thread.getPriority(), thread.getState(), prevState);
}
}

运行后的打印结果:

method     name         id  priority current state previous state
------     ----         --  -------- ------------- --------------
main       Thread#0     9   10       RUNNABLE      NEW           
main       Thread-1     10  1        RUNNABLE      NEW           
main       Thread-2     11  10       RUNNABLE      NEW           
main       Thread#3     12  1        RUNNABLE      NEW           
main       Thread-4     13  10       RUNNABLE      NEW           
main       Thread-5     14  1        RUNNABLE      NEW           
main       Thread#6     15  10       RUNNABLE      NEW           
main       Thread-7     16  5        RUNNABLE      NEW           
main       Thread-8     17  10       RUNNABLE      NEW           
main       Thread#9     18  1        RUNNABLE      NEW           
main       Thread#0     9   10       TIMED_WAITING RUNNABLE      
main       Thread-1     10  1        TIMED_WAITING RUNNABLE      
main       Thread-2     11  10       TIMED_WAITING RUNNABLE      
main       Thread#3     12  1        TIMED_WAITING RUNNABLE      
main       Thread-4     13  10       TIMED_WAITING RUNNABLE      
main       Thread-5     14  1        TIMED_WAITING RUNNABLE      
main       Thread#6     15  10       TIMED_WAITING RUNNABLE      
main       Thread-7     16  5        TIMED_WAITING RUNNABLE      
main       Thread-8     17  10       TIMED_WAITING RUNNABLE      
main       Thread#9     18  1        TIMED_WAITING RUNNABLE      
main       Thread#0     9   10       BLOCKED       TIMED_WAITING 
main       Thread-1     10  1        TERMINATED    TIMED_WAITING 
main       Thread-2     11  10       TERMINATED    TIMED_WAITING 
main       Thread#3     12  1        TERMINATED    TIMED_WAITING 
main       Thread-4     13  10       TERMINATED    TIMED_WAITING 
main       Thread-5     14  1        TERMINATED    TIMED_WAITING 
main       Thread#6     15  10       TERMINATED    TIMED_WAITING 
main       Thread-7     16  5        TERMINATED    TIMED_WAITING 
main       Thread-8     17  10       TERMINATED    TIMED_WAITING 
main       Thread#9     18  1        TERMINATED    TIMED_WAITING

运行结果并不是固定不变的,每次运行结果都不太一样。

在程序中,这几个重要的方法都演示到了:

  • 通过ThreadsetName设置线程的线程名,以及getName获取线程名。
  • 通过ThreadgetId获取线程的id。
  • 通过ThreadsetPriority设置线程的优先级,以及getPriority获取线程的优先级。
  • 通过ThreadgetState获取线程的状态,但并没有提供对应的set方法给我们设置线程的状态,毕竟线程的调度都是由线程调度器决定的。