获取/设置线程信息

线程的信息相关属性:

  • ID : 线程的唯一标识
  • Name : 线程名称
  • Priority : 优先级 . 1(最低) - 10(最高) . 不建议修改线程的优先级
  • Status : 状态
    • new
    • runnable
    • blocked
    • waiting
    • time waiting
    • terminated

任务

在上一节的任务的基础上增加显示线程的信息

实现

本节的示例代码在 com.elanzone.books.noteeg.chpt1.sect03 package中

  • 线程类和上一节无区别
  • 控制类

    • 使用 Thread.State 数组记录状态信息
        Thread.State status[] = new Thread.State[Calculator.ThreadNum];
    
    • 设置线程的优先级 (例子中把奇数编号的线程设置成最低优先级;偶数编号的线程设置成最高优先级)
        threads[i] = new Thread(new Calculator(i));
        if ((i%2) == 0) {
            threads[i].setPriority(Thread.MAX_PRIORITY);
        } else {
            threads[i].setPriority(Thread.MIN_PRIORITY);
        }
    
    • 为了避免影响线程的执行,将线程状态及其变化信息写到另一个文件
        // 使用log.txt文件记录线程的初始状态 (此时状态应该为 new)
        FileWriter file;
        try {
            file = new FileWriter(".\\data\\log.txt");
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        PrintWriter pw = new PrintWriter(file);
    
    • 记录线程状态信息
        for (int i = 0; i < Calculator.ThreadNum; i++) {
            pw.println("Main : Status of Thread "+i+" : " + threads[i].getState());
            status[i]=threads[i].getState();
        }
    
    • 在线程状态变化时, 输出线程状态变化信息
        for (int i = 0; i < Calculator.ThreadNum; i++) {
            if (threads[i].getState() != status[i]) {
                writeThreadInfo(pw, threads[i], status[i]);
                status[i] = threads[i].getState();
            }
        }
    
    • 当所有线程的状态都为 TERMINATED 时结束
        boolean finish = false;
        while (!finish) {
    
            // ...
    
            // 当所有线程的状态都为 TERMINATED 时结束
            finish = true;
            for (int i = 0; i < Calculator.ThreadNum; i++) {
                finish = finish && (threads[i].getState() == Thread.State.TERMINATED);
            }
        }
    
    • writeThreadInfo
        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");
        }
    
    • 在项目根目录创建 data/log.txt 文件

工作原理

运行并观察运行结果。

  • Thread 类有属性存储线程的所有信息
  • JVM 随时根据线程的优先级来选择一个使用 CPU 并根据情况更新所有线程的实际状态
  • 如果不给线程指定名称,JVM 将自动按 Thread-XX (XX为数字)格式为其指定名称
  • 编程人员不能修改线程的 ID 和 status (未提供这2个属性的setter方法)

了解更多

  • 如何从 Runnable 接口的实现类中获得线程的信息?
    使用 Thread 的静态方法 currentThread() 获得当前正在运行 Runnable 对象的 Thread 对象

  • 如果优先级范围不在 1 和 10 之间,setPriority 方法将抛出 IllegalArgumentException 异常