我有一个“客户端”EJB
,可以调用4个Asynchronous
EJB
,并且应该让它们全部运行5秒钟。 5秒后,“客户端”EJB从已完成运行的Future
对象收集就绪结果,并返回输出。
我在客户端部分“等待”时遇到问题。我试图调用future.get(5, TimeUnit.MILLISECONDS)
似乎有时异步EJB
在超时后开始运行。
有没有正确的方法呢?
1)在Future
中收集Map
个对象:
Map<String, Future> futureMap = new HashMap<String, Future>();
for (String userID: users) {
Future<Set<FrontPageData>> test = util.asyncGetData(userID);
futureMap.put(serviceID, test);
}
return futureMap;
2)然后我从Future
个对象
final long now = Calendar.getInstance().getTimeInMillis();
final long end = now + TimeUnit.SECONDS.toMillis(5)
Map<String, Object> output = new HashMap<String, Object>();
Object data;
for (String userID: futureMap.keySet()) {
Future future= futureMap.get(userID);
try {
//check how much time left till the end
long timeout = end - Calendar.getInstance().getTimeInMillis();
data = future.get(timeout, TimeUnit.MILLISECONDS);
output.put(userID, data);
} catch (Exception e) {//write to logs
}
}
return output;
}
谢谢
答案 0 :(得分:0)
我认为您的客户端不应该知道是否仍需要安排异步代码或者是否已经运行了5秒钟的详细信息。
所有客户都应关注的是总等待时间。由于没有系统拥有无限的资源,因此不能保证异步代码立即开始运行。
如果要将实际执行时间限制为5秒,唯一可行的方法是在执行代码的bean中执行此操作。
P.S。
与您的问题无关,但为什么这种奇怪的超时计算?你现在“现在+ 5秒 - 现在”,这又是5秒。
而且,如果迭代Map并同时需要值和键,则可以遍历entrySet,而不是遍历键集,然后为每个键执行get()
。