据我了解,ThreadpoolExecutor具有两个主要的数据结构(workers,workQueue)来管理任务.worker(Set)的线程将一直运行直到执行器关闭,而workerQueue则将所有任务交给执行器。但是按照代码我没有看到所有任务都被添加到workQueue.task仅在第1361行的队列中添加了,在每种情况下都不会执行。

最佳答案

实际上,workQueue实际上并不会将所有任务都提交给执行者。这是#execute(Runnable)的主要部分(使用this作为引用,您可能正在使用fernflower反编译的源代码或其他版本,或任何其他版本);

 1323           int c = ctl.get();
 1324           if (workerCountOf(c) < corePoolSize) {
 1325               if (addWorker(command, true))
 1326                   return;
 1327               c = ctl.get();
 1328           }
 1329           if (isRunning(c) && workQueue.offer(command)) {
 1330               int recheck = ctl.get();
 1331               if (! isRunning(recheck) && remove(command))
 1332                   reject(command);
 1333               else if (workerCountOf(recheck) == 0)
 1334                   addWorker(null, false);
 1335           }
 1336           else if (!addWorker(command, false))
 1337               reject(command);

此代码包含3个步骤:
  • 检查执行程序是否可以添加工作程序。如果可以,请使用新工作程序
  • 如果不是,请尝试将其添加到workQueue
  • 如果其他所有方法均失败,请拒绝

  • 与您的问题有关的案例是第一步,在此过程中,代码将在添加任何内容之前返回。实际上,事实并非如此,Worker的构造函数具有一个可运行的参数,这是它的第一个任务。每当TPE添加新工作程序时,提交的可运行文件是在该工作程序中运行的第一个任务。如果找到了#runWorker(Worker)方法,它将运行第一个任务,或者等待上述workQueue中存在任务。

    09-10 13:49