测试并发应用(三)监控Executor框架

声明:本文是《 Java 7 Concurrency Cookbook 》的第八章, 作者: Javier Fernández González 译者:郑玉婷

监控Executor框架

Executor 框架提供从线程的创建和管理来分别实现任务来执行这些任务的机制。如果你使用一个执行者,你只需要实现 Runnable 对象并把他们发送给执行者。 执行者的责任是管理线程。当你发一个任务给执行者,它会尝试使用pooled线程来执行这个任务,来避免创建新的任务。此机制由 Executor 接口提供,它是以 ThreadPoolExecutor 类来实现的。

在这个指南,你将学习从ThreadPoolExecutor执行者可以获取的信息和如何获取这些信息。

准备

指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。

怎么做呢…

按照这些步骤来实现下面的例子::


//1. 创建一个类,名为 Task,并实现 Runnable 接口.
public class Task implements Runnable {

//2. 声明一个私有 long 属性,名为 milliseconds.
private long milliseconds;

//3. 实现类的构造函数,初始化它的属性。
public Task (long milliseconds) {
this.milliseconds=milliseconds;
}

//4. 实现 run() 方法。通过 milliseconds 属性让线程进入一段时间休眠。
@Override
public void run() {
System.out.printf("%s: Begin/n",Thread.currentThread(). getName());
try {
TimeUnit.MILLISECONDS.sleep(milliseconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s: End/n",Thread.currentThread(). getName());
}

//5. 创建例子的主类通过创建一个类,名为 Main 并添加 main()方法。
public class Main {

public static void main(String[] args) throws Exception {

//6. 使用Executors类的newCachedThreadPool()方法创建新的 Executor 对象。
ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors. newCachedThreadPool();

//7. 创建并提交10个 Task 对象给执行者。用随机数字初始化任务。
Random random=new Random();
for (int i=0; i<10; i++) {
Task task=new Task(random.nextInt(10000));
executor.submit(task);
}

//8. 创建迭代为5的for循环。在每步,传递执行者调用 showLog() 方法写相关信息,并让线程休眠1秒。
for (int i=0; i<5; i++){
showLog(executor);
TimeUnit.SECONDS.sleep(1);
}

//9. 使用 shutdown() 方法关闭执行者。
executor.shutdown();

//10. 另创建迭代为5的for循环。在每步,传递执行者调用 showLog() 方法写相关信息,并让线程休眠1秒。
for (int i=0; i<5; i++){
showLog(executor);
TimeUnit.SECONDS.sleep(1);
}

//11. 使用 awaitTermination() 方法等待执行者的终结。
executor.awaitTermination(1, TimeUnit.DAYS);

//12. 显示一条结束程序的信息。
System.out.printf("Main: End of the program./n");
}

//13. 实现 showLog() 方法,接收 Executor 作为参数。写关于pool的大小,任务的数量,和执行者状态的信息。
private static void showLog(ThreadPoolExecutor executor) {
System.out.printf("*********************");
System.out.printf("Main: Executor Log");
System.out.printf("Main: Executor: Core Pool Size:%d/n",executor.getCorePoolSize());
System.out.printf("Main: Executor: Pool Size: %d/n",executor. getPoolSize());
System.out.printf("Main: Executor: Active Count:%d/n",executor.getActiveCount());
System.out.printf("Main: Executor: Task Count: %d/n",executor. getTaskCount());
System.out.printf("Main: Executor: Completed Task Count:%d/n",executor.getCompletedTaskCount());
System.out.printf("Main: Executor: Shutdown: %s/n",executor. isShutdown());
System.out.printf("Main: Executor: Terminating:%s/n",executor.isTerminating());
System.out.printf("Main: Executor: Terminated: %s/n",executor. isTerminated());
System.out.printf("*********************/n");
}

它是如何工作的…

在这个指南里,你实现了一个任务,它对它的执行线程进行了一段随机毫秒数的阻塞。然后,你发送10个任务给执行者,并且当你正在等待它们的终结的同时,你已经把关于执行者的状态的信息写入到操控台。你使用了以下的方法来获取 Executor 对象的状态:

  • getCorePoolSize(): 此方法返回一个int数,表示线程的核心数。它是当执行者没有执行任何任务时,在内部线程池的线程数。
  • getPoolSize(): 此方法返回一个int数,表示内部线程池的真实大小。
  • getActiveCount(): 此方法返回一个int数,表示当前执行任务的线程数。
  • getTaskCount(): 此方法返回一个long数,表示已经分配执行的任务数。
  • getCompletedTaskCount(): 此方法返回一个long数,表示已经被这个执行者执行并结束执行的任务数。
  • isShutdown(): 当 执行的 shutdown() 方法被调用来结束执行时,此方法返回 Boolean 值。
  • isTerminating(): 当执行者正在操作shutdown(),但是还没结束时,此方法返回 Boolean 值。
  • isTerminated(): 当这个执行者结束执行时,此方法返回 Boolean 值。

参见

第四章,线程执行者:创建线程执行者
第七章,自定义并发类:自定义ThreadPoolExecutor类
第七章,自定义并发类:实现基于优先的执行者类

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/140832.html

(0)
上一篇 2021年9月5日
下一篇 2021年9月5日

相关推荐

发表回复

登录后才能评论