我正在开发一个程序,该程序可以发送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();