Module java.base

Class ThreadPoolExecutor

java.lang.Object
java.util.concurrent.AbstractExecutorService
java.util.concurrent.ThreadPoolExecutor
所有已实现的接口:
AutoCloseable, Executor, ExecutorService
直接已知的子类:
ScheduledThreadPoolExecutor

public class ThreadPoolExecutor extends AbstractExecutorService
一个ExecutorService,使用可能有多个池化线程之一来执行每个提交的任务,通常使用Executors工厂方法进行配置。

线程池解决了两个不同的问题:当执行大量异步任务时,通常提供了更好的性能,因为减少了每个任务调用的开销,并且提供了一种限制和管理资源(包括线程)的方式,用于执行一组任务时所消耗的资源。每个ThreadPoolExecutor还维护一些基本统计信息,例如已完成任务的数量。

为了在各种上下文中有用,该类提供了许多可调参数和可扩展挂钩。但是,建议程序员使用更方便的Executors工厂方法Executors.newCachedThreadPool()(无界线程池,具有自动线程回收),Executors.newFixedThreadPool(int)(固定大小线程池)和Executors.newSingleThreadExecutor()(单个后台线程),这些方法预配置了最常见的使用场景设置。否则,在手动配置和调整此类时,请使用以下指南:

核心和最大池大小
ThreadPoolExecutor将根据由corePoolSize(参见getCorePoolSize())和maximumPoolSize(参见getMaximumPoolSize())设置的边界自动调整池大小。当在方法execute(Runnable)中提交新任务时,如果运行的线程少于corePoolSize个,则会创建一个新线程来处理请求,即使其他工作线程处于空闲状态。如果运行的线程少于maximumPoolSize个,则只有在队列已满时才会创建一个新线程来处理请求。通过将corePoolSize和maximumPoolSize设置为相同,可以创建一个固定大小的线程池。通过将maximumPoolSize设置为一个基本无限的值,例如Integer.MAX_VALUE,可以使池容纳任意数量的并发任务。通常,在构造时仅设置核心和最大池大小,但也可以使用setCorePoolSize(int)setMaximumPoolSize(int)动态更改它们。
按需构建
默认情况下,即使核心线程最初只有在新任务到达时才会创建和启动,但可以使用方法prestartCoreThread()prestartAllCoreThreads()动态覆盖此行为。如果使用非空队列构造池,则可能需要预启动线程。
创建新线程
使用ThreadFactory创建新线程。如果没有另外指定,将使用Executors.defaultThreadFactory(),它创建的线程都在同一个ThreadGroup中,并具有相同的NORM_PRIORITY优先级和非守护进程状态。通过提供不同的ThreadFactory,可以更改线程的名称、线程组、优先级、守护状态等。如果ThreadFactory在被要求创建线程时通过从newThread返回null失败,则执行程序将继续,但可能无法执行任何任务。线程应具有"modifyThread" RuntimePermission。如果使用池的工作线程或其他线程不具有此权限,则服务可能会受到影响:配置更改可能无法及时生效,关闭池可能仍处于可能但未完成终止状态。
保持活动时间
如果池当前的线程数超过corePoolSize个,则如果它们处于空闲状态超过keepAliveTime(参见getKeepAliveTime(TimeUnit)),则多余的线程将被终止。这提供了一种在池未被积极使用时减少资源消耗的方法。如果池稍后变得更活跃,将会构建新线程。此参数也可以使用方法setKeepAliveTime(long, TimeUnit)动态更改。使用Long.MAX_VALUE TimeUnit.NANOSECONDS的值有效地禁用了空闲线程在关闭之前的终止。默认情况下,保持活动策略仅在有超过corePoolSize个线程时适用,但方法allowCoreThreadTimeOut(boolean)可用于将此超时策略也应用于核心线程,只要keepAliveTime值非零。
排队
任何BlockingQueue都可以用于传输和保存提交的任务。使用此队列会影响池大小:
  • 如果运行的线程少于corePoolSize个,则执行程序始终更喜欢添加新线程而不是排队。
  • 如果运行的线程数达到corePoolSize或更多,则执行程序始终更喜欢将请求排队而不是添加新线程。
  • 如果无法将请求排队,则会创建一个新线程,除非这将超过maximumPoolSize,在这种情况下,任务将被拒绝。
有三种一般的排队策略:
  1. 直接移交。 一个工作队列的一个很好的默认选择是一个SynchronousQueue,它将任务直接移交给线程而不保留它们。在这里,如果没有立即可用于运行任务的线程,则尝试排队任务将失败,因此将构建一个新线程。此策略避免了在处理可能具有内部依赖关系的请求集时出现死锁。直接移交通常需要无限的maximumPoolSizes以避免拒绝新提交的任务。这反过来又可能导致线程无限增长,因为命令继续以平均更快的速度到达而无法处理。
  2. 无界队列。 使用无界队列(例如没有预定义容量的LinkedBlockingQueue)将导致新任务在所有corePoolSize线程都忙碌时等待在队列中。因此,永远不会创建超过corePoolSize个线程。(因此,maximumPoolSize的值不会产生任何效果。)当每个任务完全独立于其他任务时,这可能是合适的,因此任务不会影响彼此的执行;例如,在Web页面服务器中。虽然这种排队方式可以在平滑处理瞬时请求突发时很有用,但当命令继续以平均更快的速度到达而无法处理时,可能会导致无限的工作队列增长。
  3. 有界队列。 有界队列(例如,ArrayBlockingQueue)有助于在与有限maximumPoolSizes一起使用时防止资源耗尽,但可能更难调整和控制。队列大小和最大池大小可以相互折衷:使用大队列和小池最小化CPU使用率、操作系统资源和上下文切换开销,但可能导致人为降低吞吐量。如果任务经常阻塞(例如,如果它们受I/O限制),系统可能能够为更多线程安排时间,超过您否则允许的数量。使用小队列通常需要更大的池大小,这会使CPU更忙碌,但可能会遇到无法接受的调度开销,这也会降低吞吐量。
被拒绝的任务
在方法execute(Runnable)中提交的新任务将在执行程序已关闭时被拒绝,并且当执行程序对最大线程数和工作队列容量都使用有限边界并且饱和时也会被拒绝。在任一情况下,execute方法会调用其RejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor)方法。提供了四种预定义的处理程序策略:
  1. 在默认的ThreadPoolExecutor.AbortPolicy中,处理程序在拒绝时抛出运行时RejectedExecutionException
  2. ThreadPoolExecutor.CallerRunsPolicy中,调用execute的线程本身运行任务。这提供了一个简单的反馈控制机制,可以减慢提交新任务的速率。
  3. ThreadPoolExecutor.DiscardPolicy中,无法执行的任务将被简单地丢弃。此策略仅设计用于那些永远不依赖于任务完成的罕见情况。
  4. ThreadPoolExecutor.DiscardOldestPolicy中,如果执行程序未关闭,则工作队列头部的任务将被丢弃,然后重试执行(这可能会再次失败,导致重复执行)。此策略很少可接受。在几乎所有情况下,您还应该取消任务以导致任何等待其完成的组件中的异常,并/或记录失败,如ThreadPoolExecutor.DiscardOldestPolicy文档中所示。
可以定义和使用其他类型的RejectedExecutionHandler类。这样做需要一些谨慎,特别是当策略设计为仅在特定容量或排队策略下工作时。
钩子方法
此类提供了protected可重写的beforeExecute(Thread, Runnable)afterExecute(Runnable, Throwable)方法,在每个任务执行前后调用。这些方法可用于操纵执行环境;例如,重新初始化ThreadLocals、收集统计信息或添加日志条目。此外,方法terminated()可以被重写以执行Executor完全终止后需要执行的任何特殊处理。

如果钩子、回调或BlockingQueue方法抛出异常,则内部工作线程可能会失败、突然终止,并可能被替换。

队列维护
方法getQueue()允许访问工作队列以进行监视和调试。强烈不建议将此方法用于其他任何目的。提供了两个方法,remove(Runnable)purge(),可用于在大量排队任务被取消时协助进行存储回收。
回收
在程序中不再引用且没有剩余线程的池可能会在不明确关闭的情况下被回收(垃圾回收)。您可以通过设置适当的保持活动时间、使用零核心线程的下限和/或设置allowCoreThreadTimeOut(boolean)来配置池,以允许所有未使用的线程最终终止。

扩展示例。这个类的大多数扩展都会重写一个或多个受保护的挂钩方法。例如,这里是一个子类,添加了一个简单的暂停/恢复功能:

 
 class PausableThreadPoolExecutor extends ThreadPoolExecutor {
   private boolean isPaused;
   private ReentrantLock pauseLock = new ReentrantLock();
   private Condition unpaused = pauseLock.newCondition();

   public PausableThreadPoolExecutor(...) { super(...); }

   protected void beforeExecute(Thread t, Runnable r) {
     super.beforeExecute(t, r);
     pauseLock.lock();
     try {
       while (isPaused) unpaused.await();
     } catch (InterruptedException ie) {
       t.interrupt();
     } finally {
       pauseLock.unlock();
     }
   }

   public void pause() {
     pauseLock.lock();
     try {
       isPaused = true;
     } finally {
       pauseLock.unlock();
     }
   }

   public void resume() {
     pauseLock.lock();
     try {
       isPaused = false;
       unpaused.signalAll();
     } finally {
       pauseLock.unlock();
     }
   }
 }
自 JDK 版本:
1.5
  • Constructor Details

    • ThreadPoolExecutor

      public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
      创建一个具有给定初始参数、默认线程工厂默认拒绝执行处理程序的新 ThreadPoolExecutor

      可能更方便地使用 Executors 工厂方法之一,而不是使用此通用构造函数。

      参数:
      corePoolSize - 保留在池中的线程数,即使它们处于空闲状态,除非设置了 allowCoreThreadTimeOut
      maximumPoolSize - 允许在池中的最大线程数
      keepAliveTime - 当线程数大于核心数时,这是多余的空闲线程等待新任务的最长时间,然后终止。
      unit - keepAliveTime 参数的时间单位
      workQueue - 在执行之前保存任务的队列。此队列仅保存由 execute 方法提交的 Runnable 任务。
      抛出:
      IllegalArgumentException - 如果以下情况之一成立:
      corePoolSize < 0
      keepAliveTime < 0
      maximumPoolSize <= 0
      maximumPoolSize < corePoolSize
      NullPointerException - 如果 workQueue 为 null
    • ThreadPoolExecutor

      public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)
      创建一个具有给定初始参数和默认拒绝执行处理程序的新 ThreadPoolExecutor
      参数:
      corePoolSize - 保留在池中的线程数,即使它们处于空闲状态,除非设置了 allowCoreThreadTimeOut
      maximumPoolSize - 允许在池中的最大线程数
      keepAliveTime - 当线程数大于核心数时,这是多余的空闲线程等待新任务的最长时间,然后终止。
      unit - keepAliveTime 参数的时间单位
      workQueue - 在执行之前保存任务的队列。此队列仅保存由 execute 方法提交的 Runnable 任务。
      threadFactory - 执行程序创建新线程时使用的工厂
      抛出:
      IllegalArgumentException - 如果以下情况之一成立:
      corePoolSize < 0
      keepAliveTime < 0
      maximumPoolSize <= 0
      maximumPoolSize < corePoolSize
      NullPointerException - 如果 workQueuethreadFactory 为 null
    • ThreadPoolExecutor

      public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
      创建一个具有给定初始参数和默认线程工厂的新 ThreadPoolExecutor
      参数:
      corePoolSize - 保留在池中的线程数,即使它们处于空闲状态,除非设置了 allowCoreThreadTimeOut
      maximumPoolSize - 允许在池中的最大线程数
      keepAliveTime - 当线程数大于核心数时,这是多余的空闲线程等待新任务的最长时间,然后终止。
      unit - keepAliveTime 参数的时间单位
      workQueue - 在执行之前保存任务的队列。此队列仅保存由 execute 方法提交的 Runnable 任务。
      handler - 当执行由于线程边界和队列容量而被阻塞时使用的处理程序
      抛出:
      IllegalArgumentException - 如果以下情况之一成立:
      corePoolSize < 0
      keepAliveTime < 0
      maximumPoolSize <= 0
      maximumPoolSize < corePoolSize
      NullPointerException - 如果 workQueuehandler 为 null
    • ThreadPoolExecutor

      public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
      创建一个具有给定初始参数的新 ThreadPoolExecutor
      参数:
      corePoolSize - 保留在池中的线程数,即使它们处于空闲状态,除非设置了allowCoreThreadTimeOut
      maximumPoolSize - 允许在池中的最大线程数
      keepAliveTime - 当线程数大于核心数时,这是多余的空闲线程在终止之前等待新任务的最长时间。
      unit - keepAliveTime参数的时间单位
      workQueue - 在执行任务之前用于保存任务的队列。此队列仅保存由execute方法提交的Runnable任务。
      threadFactory - 执行器创建新线程时要使用的工厂
      handler - 当执行由于达到线程边界和队列容量而被阻塞时要使用的处理程序
      抛出:
      IllegalArgumentException - 如果以下情况之一成立:
      corePoolSize < 0
      keepAliveTime < 0
      maximumPoolSize <= 0
      maximumPoolSize < corePoolSize
      NullPointerException - 如果workQueuethreadFactoryhandler为null
  • Method Details

    • execute

      public void execute(Runnable command)
      在将来的某个时间执行给定的任务。任务可以在新线程中执行,也可以在现有的池线程中执行。如果无法提交任务以供执行,要么是因为此执行器已关闭,要么是因为其容量已达到,那么任务将由当前的RejectedExecutionHandler处理。
      参数:
      command - 要执行的任务
      抛出:
      RejectedExecutionException - 由RejectedExecutionHandler自行决定,如果无法接受任务以供执行
      NullPointerException - 如果command为null
    • shutdown

      public void shutdown()
      启动一个有序关闭,其中将执行先前提交的任务,但不会接受新任务。如果已经关闭,则调用不会有额外效果。

      此方法不会等待先前提交的任务完成执行。使用awaitTermination来完成。

      抛出:
      SecurityException - 如果存在安全管理器并且关闭此ExecutorService可能操纵调用者无权修改的线程,因为它不持有RuntimePermission("modifyThread"),或者安全管理器的checkAccess方法拒绝访问。
    • shutdownNow

      public List<Runnable> shutdownNow()
      尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。这些任务在从此方法返回时从任务队列中移除。

      此方法不会等待正在执行的任务终止。使用awaitTermination来完成。

      Thread.interrupt()中断任务; 任何未能响应中断的任务可能永远不会终止。

      返回:
      从未开始执行的任务列表
      抛出:
      SecurityException - 如果存在安全管理器并且关闭此ExecutorService可能操纵调用者无权修改的线程,因为它不持有RuntimePermission("modifyThread"),或者安全管理器的checkAccess方法拒绝访问。
    • isShutdown

      public boolean isShutdown()
      从接口复制的描述: ExecutorService
      如果此执行器已关闭,则返回true
      返回:
      如果此执行器已关闭,则返回true
    • isTerminating

      public boolean isTerminating()
      如果此执行器在调用shutdown()shutdownNow()后正在终止但尚未完全终止,则返回true。此方法可能对调试很有用。在关闭后足够长时间后返回true可能表明提交的任务已忽略或抑制中断,导致此执行器无法正确终止。
      返回:
      如果正在终止但尚未终止,则返回true
    • isTerminated

      public boolean isTerminated()
      从接口复制的描述: ExecutorService
      如果所有任务在关闭后已完成,则返回true。请注意,除非首先调用shutdownshutdownNow,否则isTerminated永远不会返回true
      返回:
      如果所有任务在关闭后已完成,则返回true
    • awaitTermination

      public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException
      从接口复制的描述: ExecutorService
      阻塞,直到所有任务在关闭请求后完成执行,或超时发生,或当前线程被中断,以先发生者为准。
      参数:
      timeout - 等待的最长时间
      unit - 超时参数的时间单位
      返回:
      如果此执行器终止,则返回true,如果超时在终止之前过期,则返回false
      抛出:
      InterruptedException - 在等待时被中断
    • finalize

      @Deprecated(since="9", forRemoval=true) protected void finalize()
      Deprecated, for removal: This API element is subject to removal in a future version.
      Finalization has been deprecated for removal. See Object.finalize() for background information and details about migration options.
      从类复制的描述: Object
      当垃圾收集确定对象不再有引用时,垃圾收集器在对象上调用finalize。子类覆盖finalize方法以处理系统资源或执行其他清理操作。

      在禁用或删除了终结时运行的Java虚拟机中,垃圾收集器永远不会调用finalize()。在启用了终结的Java虚拟机中,垃圾收集器可能会在不确定的延迟后才调用finalize

      finalize的一般约定是,当Java虚拟机确定没有任何方式可以让任何尚未死亡的线程访问此对象时,除非由其他对象或类的终结采取的操作导致另一个对象或类的终结,否则将调用它。 finalize方法可以执行任何操作,包括再次使此对象可供其他线程使用; 但是,finalize的通常目的是在对象被不可撤销地丢弃之前执行清理操作。例如,表示输入/输出连接的对象的finalize方法可能执行显式I/O事务以断开连接,然后才永久丢弃对象。

      Object类的finalize方法不执行任何特殊操作; 它只是正常返回。 Object的子类可以覆盖此定义。

      Java编程语言不保证哪个线程将为给定对象调用finalize方法。但是,保证调用finalize的线程在调用finalize时不会持有任何用户可见的同步锁。如果由finalize方法抛出未捕获的异常,则该异常将被忽略,并且该对象的终结将终止。

      在为对象调用finalize方法后,直到Java虚拟机再次确定没有任何方式可以让任何尚未死亡的线程访问此对象,包括其他对象或类的终结可能采取的操作,此时对象可能被丢弃。

      finalize方法由Java虚拟机最多调用一次,用于任何给定对象。

      finalize方法抛出的任何异常都会导致此对象的终结被停止,但否则会被忽略。

      覆盖:
      finalize 在类 Object
      实现注意:
      此类的早期版本具有一个终结方法,该方法关闭此执行器,但在此版本中,终结不执行任何操作。
      参见:
    • setThreadFactory

      public void setThreadFactory(ThreadFactory threadFactory)
      设置用于创建新线程的线程工厂。
      参数:
      threadFactory - 新线程工厂
      抛出:
      NullPointerException - 如果threadFactory为null
      参见:
    • getThreadFactory

      public ThreadFactory getThreadFactory()
      返回用于创建新线程的线程工厂。
      返回:
      当前线程工厂
      参见:
    • setRejectedExecutionHandler

      public void setRejectedExecutionHandler(RejectedExecutionHandler handler)
      设置无法执行任务的新处理程序。
      参数:
      handler - 新处理程序
      抛出:
      NullPointerException - 如果处理程序为null
      参见:
    • getRejectedExecutionHandler

      public RejectedExecutionHandler getRejectedExecutionHandler()
      返回无法执行任务的当前处理程序。
      返回:
      当前处理程序
      参见:
    • setCorePoolSize

      public void setCorePoolSize(int corePoolSize)
      设置核心线程数。这将覆盖构造函数中设置的任何值。如果新值小于当前值,则下次空闲时将终止多余的现有线程。如果更大,将根据需要启动新线程来执行任何排队的任务。
      参数:
      corePoolSize - 新的核心大小
      抛出:
      IllegalArgumentException - 如果corePoolSize < 0corePoolSize大于最大池大小
      参见:
    • getCorePoolSize

      public int getCorePoolSize()
      返回核心线程数。
      返回:
      核心线程数
      参见:
    • prestartCoreThread

      public boolean prestartCoreThread()
      启动一个核心线程,使其空闲等待工作。这将覆盖默认策略,仅在执行新任务时才启动核心线程。如果所有核心线程已经启动,则此方法将返回false
      返回:
      如果启动了一个线程,则为true
    • prestartAllCoreThreads

      public int prestartAllCoreThreads()
      启动所有核心线程,使它们空闲等待工作。这将覆盖默认策略,仅在执行新任务时才启动核心线程。
      返回:
      启动的线程数
    • allowsCoreThreadTimeOut

      public boolean allowsCoreThreadTimeOut()
      如果此池允许核心线程在没有任务到达时超时并终止,则返回true,如果需要时将其替换。当为true时,适用于非核心线程的相同保持活动策略也适用于核心线程。当为false(默认值)时,核心线程永远不会因缺少传入任务而终止。
      返回:
      如果允许核心线程超时,则为true,否则为false
      自从:
      1.6
    • allowCoreThreadTimeOut

      public void allowCoreThreadTimeOut(boolean value)
      设置控制核心线程是否可以超时并在没有任务到达时终止并在需要时替换的策略。当为false时,核心线程永远不会因缺少传入任务而终止。当为true时,适用于非核心线程的相同保持活动策略也适用于核心线程。为避免持续线程替换,当设置为true时,保持活动时间必须大于零。通常应在池被积极使用之前调用此方法。
      参数:
      value - 如果应该超时,则为true,否则为false
      抛出:
      IllegalArgumentException - 如果值为true且当前保持活动时间不大于零
      自从:
      1.6
    • setMaximumPoolSize

      public void setMaximumPoolSize(int maximumPoolSize)
      设置允许的最大线程数。这将覆盖构造函数中设置的任何值。如果新值小于当前值,则下次空闲时将终止多余的现有线程。
      参数:
      maximumPoolSize - 新的最大值
      抛出:
      IllegalArgumentException - 如果新的最大值小于等于零,或小于核心池大小
      参见:
    • getMaximumPoolSize

      public int getMaximumPoolSize()
      返回允许的最大线程数。
      返回:
      允许的最大线程数
      参见:
    • setKeepAliveTime

      public void setKeepAliveTime(long time, TimeUnit unit)
      设置线程保持活动时间,即线程在终止之前可以保持空闲的时间量。等待此时间而不处理任务的线程将在池中当前存在的核心线程数多于的情况下终止,或者如果此池允许核心线程超时。这将覆盖构造函数中设置的任何值。
      参数:
      time - 等待的时间。时间值为零将导致多余线程在执行任务后立即终止。
      unit - time参数的时间单位
      抛出:
      IllegalArgumentException - 如果time小于零或如果time为零且allowsCoreThreadTimeOut
      参见:
    • getKeepAliveTime

      public long getKeepAliveTime(TimeUnit unit)
      返回线程保持活动时间,即线程在终止之前可以保持空闲的时间量。等待此时间而不处理任务的线程将在池中当前存在的核心线程数多于的情况下终止,或者如果此池允许核心线程超时
      参数:
      unit - 结果的所需时间单位
      返回:
      时间限制
      参见:
    • getQueue

      public BlockingQueue<Runnable> getQueue()
      返回此执行程序使用的任务队列。主要用于调试和监视。此队列可能正在使用中。检索任务队列不会阻止排队的任务执行。
      返回:
      任务队列
    • remove

      public boolean remove(Runnable task)
      如果存在,则从执行程序的内部队列中删除此任务,从而导致如果尚未启动,则不运行它。

      此方法可能作为取消方案的一部分有用。它可能无法删除在放置在内部队列之前已转换为其他形式的任务。例如,使用submit输入的任务可能会转换为保持Future状态的形式。但是,在这种情况下,可以使用方法purge()来删除已取消的那些Future。

      参数:
      task - 要移除的任务
      返回:
      如果任务已被移除,则为true
    • purge

      public void purge()
      尝试从工作队列中移除所有已取消的Future任务。此方法可用作存储回收操作,对功能没有其他影响。已取消的任务永远不会被执行,但可能会在工作队列中累积,直到工作线程可以主动删除它们。调用此方法而不是立即尝试删除它们。但是,在其他线程的干扰存在的情况下,此方法可能无法删除任务。
    • getPoolSize

      public int getPoolSize()
      返回池中当前线程的数量。
      返回:
      线程数
    • getActiveCount

      public int getActiveCount()
      返回正在执行任务的活动线程的近似数量。
      返回:
      线程数
    • getLargestPoolSize

      public int getLargestPoolSize()
      返回池中曾经同时存在的最大线程数。
      返回:
      线程数
    • getTaskCount

      public long getTaskCount()
      返回曾经被安排执行的任务的近似总数。由于任务和线程的状态在计算过程中可能动态变化,因此返回的值仅为近似值。
      返回:
      任务数
    • getCompletedTaskCount

      public long getCompletedTaskCount()
      返回已完成执行的任务的近似总数。由于任务和线程的状态在计算过程中可能动态变化,因此返回的值仅为近似值,但在连续调用中不会减少。
      返回:
      任务数
    • toString

      public String toString()
      返回标识此池及其状态的字符串,包括运行状态和估计的工作线程和任务计数的指示。
      覆盖:
      toString 在类 Object
      返回:
      标识此池及其状态的字符串
    • beforeExecute

      protected void beforeExecute(Thread t, Runnable r)
      在给定线程中执行给定的Runnable之前调用的方法。此方法由将执行任务r的线程t调用,并可用于重新初始化ThreadLocals或执行日志记录。

      此实现不执行任何操作,但可以在子类中自定义。注意:为了正确嵌套多个重写,子类通常应在此方法的末尾调用super.beforeExecute

      参数:
      t - 将运行任务r的线程
      r - 将被执行的任务
    • afterExecute

      protected void afterExecute(Runnable r, Throwable t)
      在给定的Runnable执行完成后调用的方法。此方法由执行任务的线程调用。如果非空,则Throwable是导致执行突然终止的未捕获的RuntimeExceptionError

      此实现不执行任何操作,但可以在子类中自定义。注意:为了正确嵌套多个重写,子类通常应在此方法的开头调用super.afterExecute

      注意:当操作封装在任务中(例如FutureTask)中,无论是显式地还是通过submit等方法,这些任务对象都会捕获并维护计算异常,因此它们不会导致突然终止,并且内部异常不会传递给此方法。如果您想要在此方法中捕获两种失败情况,可以进一步探测这种情况,就像这个示例子类一样,如果任务已中止,则打印直接原因或基础异常:

       
       class ExtendedExecutor extends ThreadPoolExecutor {
         // ...
         protected void afterExecute(Runnable r, Throwable t) {
           super.afterExecute(r, t);
           if (t == null
               && r instanceof Future<?>
               && ((Future<?>)r).isDone()) {
             try {
               Object result = ((Future<?>) r).get();
             } catch (CancellationException ce) {
               t = ce;
             } catch (ExecutionException ee) {
               t = ee.getCause();
             } catch (InterruptedException ie) {
               // ignore/reset
               Thread.currentThread().interrupt();
             }
           }
           if (t != null)
             System.out.println(t);
         }
       }
      参数:
      r - 已完成的可运行对象
      t - 导致终止的异常,如果执行正常完成则为null
    • terminated

      protected void terminated()
      当Executor终止时调用的方法。默认实现不执行任何操作。注意:为了正确嵌套多个重写,子类通常应在此方法中调用super.terminated