我正在开发一个程序,该程序可以发送http请求以获取文档。
我已经将所有请求项填充到队列中:

Queue<RequestItem> requestItems = buildRequest4Docs();

然后,
int threadNum = requestItems.size();
        //ExecutorService exs = Executors.newFixedThreadPool(threadNum);

        for (int i = 0; i < threadNum; i++) {
            ResponseInterface response = new CMSGOResponse();
            RequestTask task = new RequestTask(requestItems.poll(), this, response);
            task.run();
            //exs.execute(new RequestTask(requestItems.poll(), this, response));
        }
        //exs.shutdown();

我在这里感到困惑,在for循环中,任务是同时运行的吗?还是任务一个接一个地运行?

谢谢!

最佳答案

以您现在的方式,任务将被一个接一个地执行。如果您取消注释现在得到的代码作为注释,并注释RequestTask task = new RequestTask(requestItems.poll(), this, response);task.run();行,则将执行并发执行。

因此,对于并发执行,它必须如下所示:

int threadNum = requestItems.size();
ExecutorService exs = Executors.newFixedThreadPool(threadNum);

for (int i = 0; i < threadNum; i++) {
    ResponseInterface response = new CMSGOResponse();
    exs.execute(new RequestTask(requestItems.poll(), this, response));
}
exs.shutdown();
while (! exs.isTerminated()) {
    try {
        exs.awaitTermination(1L, TimeUnit.DAYS);
    }
    catch (InterruptedException e) {
        // you may or may not care here, but if you truly want to
        // wait for the pool to shutdown, just ignore the exception
        // otherwise you'll have to deal with the exception and
        // make a decision to drop out of the loop or something else.
    }
}

除此以外,我建议您不要将使用ExecutorService创建的线程数量绑定(bind)到要执行的任务数量上。将其连接到主机系统的处理器数量通常是一种更好的方法。要获取处理器数量,请使用:Runtime.getRuntime().availableProcessors()
然后在像这样初始化的执行器服务中,将项目放入队列。但这在不获取总大小的情况下很好地工作,而是通过轮询Queue直到它不返回其他数据为止。

我的提案的最终结果可能如下所示:
final int threadNum = Runtime.getRuntime().availableProcessors();
final ExecutorService exs = Executors.newFixedThreadPool(threadNum);

while (true) {
    final RequestItem requestItem = requestItems.poll();
    if (requestItem == null) {
        break;
    }
    final ResponseInterface response = new CMSGOResponse();
    exs.execute(new RequestTask(requestItem , this, response));
}
exs.shutdown();

10-04 18:37