我使用 ExecutorCompletionService 来调用 Web 服务。线程正在访问的 Web 服务会在 5 秒内返回响应。但是,completionService.take().get() 需要将近 30 秒才能从其第一个完成的线程中检索结果;而 completionService.take().get() 需要 6 秒才能从其他已完成线程中检索结果。
我知道 ExecutorCompletionService 它需要().get()一个首先完成的任务,而不是首先提交的任务。但我无法弄清楚为什么要花这么多时间(30 秒+)才能从第一个完成的线程中获得结果。为什么其他线程在控制台中声称他们需要 6 秒才能完成,但 take().get() 不会比需要 30+ 秒的线程先处理。
最初,我开始仅将 ExecutorService 与 Future 一起使用,但后来我切换到 ExecutorCompletionService 以获得更好的响应时间。但响应时间不会改变。除了我的主要代码之外,还尝试使用 ExecutorCompletionService 在 Future 中添加任务,但没有任何改变:
CompletionService executorCompletionService = new ExecutorCompletionService<>(executorService);
List<Future<List<Students>>> futures = new ArrayList<Future<Students>>();
for(..)
{
future.add(mytasks);
}
for(
int i = 0;i<futures.size();i++)
{
List<Students> result = executorCompletionService.take().get();
// Some processing here
}
ExecutorService executorService = Executors.newFixedThreadPool(4, new ThreadFactory("myThreads"));
CompletionService<List<Students>> completionService = new ExecutorCompletionService<>(executorService);for(
int i = 0;i<4;i++)
{
int thread = i;
completionService.submit(new Callable<List<Students>>() {
public List<Students> call() throws Exception {
List myList = (List<Students>) anotherApi.seviceCall(Object);
Students st = new Students();
st.setId(thread);
st.setName1("I am thread-----");
myList.add(st);
return list;
}
});
}
for(
int i = 0;i<4;i++)
{
long startTimeOfReadingThread = System.currentTimeMillis(); // start
// time of
// reading
// result
// set of
// thread
List<Students> students = completionService.take().get();
for (Students c : student) {
if (c.getName() != null && c.getName() != "" && c.getName1().equals("I am thread-----"))
System.out.println("I am thread-----" + c.getId());
}
long endTimeOfReadingThread = System.currentTimeMillis(); // end time
// when
// result
// set of
// thread is
// read
System.out.println(
"time in threads&&&&&&&&*****" + ((endTimeOfReadingThread - startTimeOfReadingThread) / 1000F));
response.addAll(students);
}executorService.shutdown();
系统输出控制台的响应时间(以秒为单位):
I am thread-----3
time in threads&&&&&&&&*****29.703
I am thread-----0
time in threads&&&&&&&&*****7.987
I am thread-----1
time in threads&&&&&&&&*****6.001
I am thread-----2
time in threads&&&&&&&&*****6.563
请帮助我纠正我做错的任何事情。我只知道,如果 4 个线程使用 Executor Completion Service 并行运行,而另一个服务被击中一个线程的时间不超过 5-6 秒,那么我的第一个完成的线程不应该超过 6-7 秒(只是像其他线程一样)。
这导致对用户的总响应时间几乎是 33 秒。