Я думаю, что лучший способ решить этот вопрос - добавить дополнительные данные в класс DeferredResult, как это рекомендовано spring docs .Точно, следующее предложение в весенних документах указывает на эту возможность.
Подклассы могут расширять этот класс, чтобы легко связать дополнительные данные или поведение с DeferredResult.Например, можно связать пользователя, использовавшегося для создания DeferredResult, путем расширения класса и добавления дополнительного свойства для пользователя.Таким образом, пользователь может легко получить доступ позже без необходимости использовать структуру данных для выполнения сопоставления.
Учитывая эту возможность, вы можете расширить DeferredResult и добавить время начала и окончания:
public class MyDeferredResult extends DeferredResult {
long startTime;
long endTime;
public MyDeferredResult(Long timeout, Object timeoutResult) {
super(timeout, timeoutResult);
this.startTime = System.currentTimeMillis();
}
@Override
public boolean setResult(Object result) {
boolean r = super.setResult(result);
this.endTime = System.currentTimeMillis();
return r;
}
public long totalTime() {
return (endTime - startTime)/1000;
}
}
Тогда ваша асинхронная служба может быть похожа на эту:
public MyDeferredResult foo() {
MyDeferredResult dr = new MyDeferredResult(5000L, "timeout");
new Thread(() -> {
Random r = new Random();
System.out.println("async task started");
try {
Thread.sleep(r.nextInt(4) * 1000 );
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("async task finished");
dr.setResult("test async result");
}).start();
deferredResults.add(dr);
return dr;
}
boolean hasResults() {
boolean result = true;
for(MyDeferredResult dr: deferredResults) {
result = result && dr.hasResult();
}
return result;
}
Наконец, в вашем тесте вы можете получить общее время каждого выполнения:
@Test
public void executionTimeTest() {
Service service = new Service();
for (int i = 0; i < 10; i++) {
service.foo();
}
while (!service.hasResults()) {
System.out.println("No result yet");
}
for(MyDeferredResult dr: service.deferredResults) {
System.out.println(dr.totalTime());
}
}