我认为解决这个问题的最好方法是在Spring docs推荐的 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;
}
}
然后,您的 Async Service 可以与此类似:
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());
}
}