创建一个固定大小的线程执行者

当您使用由 Executors 类的 newCachedThreadPool() 方法创建的基础 ThreadPoolExecutor 时,执行者正在运行的线程数目可能会是个问题。 执行者为每个接收到的任务创建一个新线程(如果池内没有空闲线程),这样如果您发送很大数目的执行时间很长的任务,系统会过载,导致应用程序的性能很差。

如果您想避免此问题,Executors 类提供了一个方法来创建一个固定大小的线程执行者。此执行者有一个最大线程数。 如果您发送超过此数目的任务,执行者不会创建更多线程,剩余的任务将被阻塞直到执行者有空闲线程。 这样就能保证执行者不会引发应用程序的性能差的问题。

任务

修改上一节的代码实现创建固定线程池大小的线程执行者.

实现

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

在上一节代码的基础上:

  • 线程类: Server

    • 构造函数: 使用 newFixedThreadPool() 方法来创建执行者, 并传递 5 作为参数
             public Server() {
        -        executor = (ThreadPoolExecutor)Executors.newCachedThreadPool();
        +        executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(5);
             }
    
    • executeTask() 方法: 调用 getTaskCount() 方法获得已发送给执行者的任务数, 将此信息输出到日志信息
                 System.out.printf("Server: Completed Tasks: %d\n",executor.getCompletedTaskCount());
        +        System.out.printf("Server: Task Count: %d\n",executor.getTaskCount());
             }
    

工作原理

本例中使用了 Executors 类的 newFixedThreadPool() 方法来创建执行者.此方法创建一个有最大线程数的执行者. 如果您发送超过最大线程数目的任务,执行者不会创建更多线程,剩余的任务将被阻塞直到执行者有空闲线程。 此方法接受最大线程数作为参数.本例中,创建了一个最多有5个线程的执行者.

了解更多

Executors 类还提供了 newSingleThreadExecutor() 方法.这是固定大小的线程执行者的一个极端例子. 它创建一个只有一个线程的执行者,这样它一次只能执行一个任务.