监控线程类

Java 9并发编程指南 目录

线程是Java并发API中最基本的元素,每个Java程序都至少有一个执行main()方法的线程,反过来main()方法启动应用的执行。当启动一个新的Thread类时,它将与应用程序的其他线程以及操作系统上的其他进程并行执行。进程和线程之间有一个关键的区别,进程是正在运行的应用实例(例如在文本处理器中编辑文件)。一个或多个线程执行完成此过程的任务,可以运行同一个应用的多个进程,例如文本处理器的两个实例。进程中的线程共享内存,而相同操作系统的进程不共享内存。

能够执行的所有类型的Java任务(Runnable、Callable或fork/join任务)都在线程中执行,所有高级Java并发机制,例如Executor框架和fork/join框架都基于线程池实现。

本节将学习关于Thread类的状态信息,以及如何获取这些信息。

准备工作

本范例通过Eclipse开发工具实现。如果使用诸如NetBeans的开发工具,打开并创建一个新的Java项目。

实现过程

通过如下步骤实现范例:

  1. 创建名为Task的类,实现Runnable接口:

    public class Task implements Runnable {
    
  2. 实现任务的run()方法:

    	@Override	
    	public void run() {
    
  3. 创建重复100次操作的循环:

    		for (int i=0; i<100; i++) {
    
  4. 在每次操作中,设置线程休眠100毫秒:

    			try {	
    				TimeUnit.MILLISECONDS.sleep(100);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    
  5. 输出线程名称和重复次数到控制台:

    			System.out.printf("%s: %d\n",Thread.currentThread().getName(),i);
    		}
    	}
    }
    
  6. 创建本范例主类,创建名为Main的类,包含main()方法:

    public class Main {
    	public static void main(String[] args) throws Exception{
    
  7. 创建名为task的Task对象:

    		Task task = new Task();
    
  8. 创建包含五个元素的Thread数组:

    		Thread threads[] = new Thread[5];
    
  9. 创建并启动五个线程执行之前创建的Task对象:

    		for (int i = 0; i < 5; i++) {
    			threads[i] = new Thread(task);
    			threads[i].setPriority(i + 1);
    			threads[i].start();
    		}
    
  10. 创建重复10次操作的循环,每次操作输出之前加载的线程信息到控制台,在内部创建重复五次操作的循环:

    		for (int j = 0; j < 10; j++) {
    			System.out.printf("Main: Logging threads\n");
    			for (int i = 0; i < threads.length; i++) {
    
  11. 输出每个线程的名称、状态、组别和堆栈跟踪的长度到控制台:

    				System.out.printf("**********************\n");
    				System.out.printf("Main: %d: Id: %d Name: %s: Priority: %d\n",i, threads[i].getId(),threads[i].getName(), threads[i].getPriority());
    				System.out.printf("Main: Status: %s\n",threads[i].getState());
    				System.out.printf("Main: Thread Group: %s\n", threads[i].getThreadGroup());
    				System.out.printf("Main: Stack Trace: \n");
    
  12. 输出线程堆栈跟踪的循环到控制台:

    				for (int t=0; t<threads[i].getStackTrace().length; t++) {
    					System.out.printf("Main: %s\n",threads[i].getStackTrace()[t]);
    				}
    				System.out.printf("**********************\n");
    			}
    
  13. 设置线程休眠1秒钟,关闭类循环:

    			TimeUnit.SECONDS.sleep(1);
    		}
    	}
    }
    

工作原理

本节使用如下方法的到Thread类的信息:

  • getId():返回线程的ID,它是唯一长整型数字,且无法更改。
  • getName():返回线程名称,如果没有设置线程名称,Java提供默认名称。
  • getPriority():返回线程执行优先级。高优先级的线程优先于低优先级的线程执行,它是int值,在线程类常量MIN_PRIORITY和MAX_PRIORITY之间。默认情况下,创建线程的优先级与Thread类常量NORM_PRIORITY指定的优先级相同。
  • getState():返回线程状态,它是Thread.State对象,Thread.State枚举具有线程的所有可能状态。
  • getThreadGroup():返回线程的ThreadGroup对象,默认情况下,线程属于相同的线程组,但可以在线程的构造函数中建立一个不同的线程组。
  • getStackTrace():返回StackTraceElement对象数组。每个对象都表示对以线程的run()方法开始的方法调用,并包括在实际执行点之前调用的所有方法。当调用新对象时,新的堆栈跟踪元素添加到数组中。当方法结束执行时,其堆栈跟踪元素从数组中移出。

扩展学习

Thread类还有其他方法,提供线程的有用信息。如下所示:

  • activeCount():返回线程组中活跃线程数。
  • dumpStack():将线程的堆栈跟踪按照标准错误输出。

更多关注

  • 第一章“线程管理”中的“创建、运行线程,设置线程属性”小节
  • 第八章“定制并发类”中的“执行器对象中使用自定义ThreadFactory”和“实现为fork/join框架生成自定义线程的ThreadFactory接口”小节
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值