《Java程序员面试秘笈》—— 1.3 线程信息的获取和设置

1.3 线程信息的获取和设置

Thread类有一些保存信息的属性,这些属性可以用来标识线程,显示线程的状态或者控制线程的优先级。

ID:保存了线程的唯一标示符。

Name:保存了线程名称

Priority:保存了线程对象的优先级。线程的优先级是从1到10,其中1是最低优先级;10是最高优先级。我们并不推荐去改变线程的优先级,然而,在需要的时候,也可以这么做。

Status:保存了线程的状态。在Java中,线程的状态有6种:new、runnable、blocked、waiting、time waiting或者 terminated。

在本节,我们将编写程序为10个线程指定名称和优先级,并且输出它们的状态信息直到线程结束。每个线程都将计算一个数字的乘法表。

准备工作
本节的范例是在Eclipse IDE里完成的。无论你使用Eclipse还是其他的IDE(比如NetBeans),都可以打开这个IDE并且创建一个新的Java工程。

范例实现
按照接下来的步骤实现本节的范例。

1.创建一个名为Calculator的类,它实现了Runnable接口。
``
public class Calculator implements Runnable {``
2.声明一个名为number的私有int属性。编写这个类的一个构造器,用来为属性number设置值。

private int number;
public Calculator(int number) {
  this.number=number;
}```
3.编写run()方法。这个方法用来执行我们创建的线程的指令,本范例中它将对指定的数字进行乘法表运算。

@Override
public void run() {
for (int i=1; i<=10; i++){

System.out.printf("%s: %d * %d = %d\n",Thread. currentThread().getName(),number,i,i*number);

}
}`
4.编写范例的主类。创建一个名为Main的类,创建的时候同时生成main()方法。

public class Main {
  public static void main(String[] args) {```
5. 创建一个容量为10的线程数组,以用来存储线程;创建一个容量为10的Thread.State数组,以用来存放这10个线程运行时的状态。

Thread threads[]=new Thread[10];
Thread.State status[]=new Thread.State[10];`
6.创建一个容量为10的Calculator对象数组,为每个对象都设置不同的数字,然后使用它们作为Thread构造器的参数来创建10个线程对象。并且将其中5个线程的优先级设置为最高,另外5个线程的优先级设置为最低。

for (int i=0; i<10; i++){
  threads[i]=new Thread(new Calculator(i));
   if ((i%2)==0){
    threads[i].setPriority(Thread.MAX_PRIORITY);
   } else {
     threads[i].setPriorit87y(Thread.MIN_PRIORITY);
   }
   threads[i].setName("Thread "+i);
}```
7.创建一个PrintWriter对象,用来把线程的状态演变写入到文件中。

try (FileWriter file = new FileWriter(".\data\log.txt");PrintWriter pw = new PrintWriter(file);){`
8.把这10个线程的状态写入文件中。现在线程的状态是NEW。

  for (int i=0; i<10; i++){
pw.println("Main : Status of Thread "+i+" : " +threads[i].getState());
       status[i]=threads[i].getState();
  }```
9.开始执行10个线程。

for (int i=0; i<10; i++){
threads[i].start();
}`
10.直到10个线程都运行完成,我们就可以查看他们的状态。所有任何一个线程的状态发生了变化,我们就会将它写入到文件中。

    boolean finish=false;
    while (!finish) {
      for (int i=0; i<10; 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<10; i++){
finish=finish &&(threads[i].getState()==State.TERMINATED);
        }
      }```
11.编写writeThreadInfo()方法,用来写下线程的ID、名称、优先级、旧的状态和新的状态。

private static void writeThreadInfo(PrintWriter pw, Thread
thread, State state) {
pw.printf("Main : Id %d - %sn",thread.getId(),thread.getName());
pw.printf("Main : Priority: %dn",thread.getPriority());
pw.printf("Main : Old State: %sn",state);
pw.printf("Main : New State: %sn",thread.getState());
pw.printf("Main : n");
}`
12.运行这个范例,然后打开log.txt文件来查看10个线程的状态演变。

工作原理
下面的截屏是log.txt文件的一部分。在这个文件里,我们可以看到最高优先级的线程比最低优先级的线程结束得早。我们也可以看到每个线程的状态演变。

这个程序的乘法表运算显示在控制台上,每个线程的状态演变记录在log.txt里。这样你可以更清楚地看到线程的演变过程。

Thread类的属性存储了线程的所有信息。JVM使用线程的priority属性来决定某一刻由哪个线程来使用CPU,并且根据线程的情景为它们设置实际状态。

如果没有为线程指定一个名字,JVM将自动给它分配一个名字,格式是Thread-XX,其中XX是一组数字。线程的ID和状态是不允许被修改的,线程类没有提供setId()和setStatus()方法来修改它们。

更多信息
通过本节,你已经学会了如何通过Thread对象访问属性信息。但是,也可以通过实现Runnable接口的对象来访问这些属性信息。如果一个线程是以Runnable对象为参数构建的,那么也可以使用Thread类的静态方法currentThread()来访问这个线程对象。

要注意的是,如果使用setPriority()方法设置的优先级不是从1到10这个范围内的值,运行时就会抛出IllegalArgumentException异常。

时间: 2024-10-23 04:40:23

《Java程序员面试秘笈》—— 1.3 线程信息的获取和设置的相关文章

《Java程序员面试秘笈》—— 面试题11 使用jar命令

面试题11 使用jar命令 Java程序员面试秘笈 请使用jar命令,将test文件夹压缩成.jar文件,并简述其压缩包的结构. 考点:对于Java程序员来说,更多情况下是使用的集成Java开发工具,例如JBuilder.Eclipse等,而对于最基本的Java编译和常见的命令行工具往往都不熟悉.这个面试题主要考察求职者对于Java命令行基本工具的使用,从而了解求职者对Java编程的熟悉程度. 出现频率: [面试题解析]熟练的Java开发者应该掌握常用的Java命令行工具.求职者应该熟练掌握ja

《Java程序员面试秘笈》—— 面试题12 如何执行mian()方法

面试题12 如何执行mian()方法 Java程序员面试秘笈 利用Java SDK中哪一条命令能够执行test的main()方法? (a)java test (b)javac test (c)java test.java (d)java test.class (e)java test.main 考点:考察求职者对java命令的熟悉程度. 出现频率: [面试题解析]求职者容易出现的错误是选择了(d).实际上,java命令后面只需要class文件的名称就可以,不用加入.class全名.如果使用jav

《Java程序员面试秘笈》—— 面试题10 类继承的建模表示方法

面试题10 类继承的建模表示方法 Java程序员面试秘笈根据图1.4的UML表示,选择一个正确的描述. (a)Box类是MyBox类的子类. (b)Box类是MyBox类的父类. (c)Box类和MyBox类是聚合关系. (d)Box类和MyBox类是一对多关系. 考点:该面试题貌似简单,在实际的面试中回答正确的却并不是很多,其实只是考察求职者对类的继承的建模表示方法的掌握程度. 出现频率: [面试题解析]Java中有两种机制来保证根据现有的类来构造新的类,那就是继承和聚合.例如,有一个盒子的类

《Java程序员面试秘笈》—— 导读

前言 Java 7并发编程实战手册 使用计算机时,可以同时做几件事情:可以一边听音乐,一边使用文字处理软件编辑文档,还可以阅读电子邮件.因为操作系统支持并发任务,从而使得这些工作得以同时进行.并发编程是一种平台和机制供多个任务或程序同时运行,并且互相通讯来交换数据(或者与其他任务进行同步等待). Java是一个并发平台,它提供了大量的类来执行Java程序中的并发任务.随着版本的不断更新发展,Java 不断地为程序员增加并发编程的开发功能.本书覆盖了Java 7并发API 中大部分重要而有用的机制

《Java程序员面试秘笈》—— 第1章 线程管理 1.1 简介

第1章 线程管理 Java 7并发编程实战手册 本章内容包括: ◆ 线程的创建和运行 ◆ 线程信息的获取和设置 ◆ 线程的中断 ◆ 线程中断的控制 ◆ 线程的休眠和恢复 ◆ 等待线程的终止 ◆ 守护线程的创建和运行 ◆ 线程中不可控异常的处理 ◆ 线程局部变量的使用 ◆ 线程的分组 ◆ 线程组中不可控异常的处理 ◆ 使用工厂类创建线程 1.1 简介 在计算机领域中,我们说的并发(Concurrency)是指一系列任务的同时运行.如果一台电脑有多个处理器或者有一个多核处理器,这个同时性(Simul

《Java程序员面试秘笈》—— 面试题6 命名Java变量

面试题6 命名Java变量 请命名以下变量. 考点:该面试题主要考察求职者的编程习惯,良好的编程习惯是一个优秀的Java开发者的必备素质.求职者应该掌握基本的Java命名规范,这样编写出来的代码才能做到够规范和易读. 出现频率: [面试题解析]在面向对象编程中,对于类.对象变量.方法等的命名是非常有技巧的,例如,大小写的区分,使用不同字母开头等.但究其本,追其源,在为一个资源命名时,应该本着描述性和唯一性两大特征,才能保证资源之间不冲突,并且便于记忆. 1.包的命名 Java包的名字都是由小写单

《Java程序员面试秘笈》—— 面试题1 简单描述Java开发包的种类

面试题1 简单描述Java开发包的种类 考点:考察求职者对于Java体系的认识,属于Java程序员的必备知识. 出现频率: [面试题解析]随着Java语言的成长和壮大,Java的开发包根据用途的不同已经分为Java EE.Java SE和Java ME 3个开发包,求职者需要列出名称,并具体描述每个开发包的用途. 参考答案: Java SDK的版本分类如下所述. Java ME:(Java Platform Micro Edition)一种以广泛的消费性产品为目的的高度优化的Java运行环境,包

《Java程序员面试秘笈》—— 1.2 线程的创建和运行

1.2 线程的创建和运行 在本章中,我们将学习如何在Java程序中创建和运行线程.在Java语言中,线程跟其他所有元素一样,都是对象(Object).Java提供了两种方式来创建线程: ◆ 继承Thread类,并且覆盖run()方法. ◆ 创建一个实现Runnable接口的类.使用带参数的Thread构造器来创建Thread对象.这个参数就是实现Runnable接口的类的一个对象. 在本章中,我们将使用第二种方法创建一个简单的程序,这个程序将创建并运行10个线程.每个线程用以计算和打印乘以1-1

《Java程序员面试秘笈》—— 面试题4 列出你熟悉的Java开发工具

面试题4 列出你熟悉的Java开发工具 考点:该问题一般会在面试时出现,主要是看求职者是否熟悉常用的Java开发工具,因为一个项目开发团队会使用一种固定的开发工具,只有求职者能够熟练使用该工具,才能够快速融入该团队. 出现频率: [面试题解析]Java作为一种跨平台开发语言,由于其开源性,各个公司和社区组织,都推出了各自的Java开发工具,这也是Java开发体系同微软的开发体系的区别之一.不同的项目开发团队一般都有自己熟悉的开发工具或者开发环境,求职者只有熟练使用不同的开发工具,才能适应项目开发