如何通过同步方法正确调用异步服务

时间:2016-12-09 14:11:36

标签: java asynchronous design-patterns service

我是客户,使用服务。

我调用异步工作的服务方法。这意味着该方法立即返回一些标识符(id),然后我应该定期检查此ID,任务是否完成。例如,服务提供三种方法:

service.startTask(someData) //starts task and returns its id
service.isTaskFinished(taskId) // checks is task finished
service.getTaskResult(taskId) //returns task results

我需要在java中实现方法,启动任务,等待任务完成后再返回任务结果。只有我能想象的解决方案是:

...
public Object invokeAsyncTaskAndGetResults(int someData) {

    int taskId = service.startTask(someData);

    int sleepTime = 1000;
    int maxCheckCount = 5;
    boolean hasResults = false;

    int i = 1;
    while (i <= maxCheckCount && !hasResults) {
        hasResults = service.isTaskFinished(taskId );
        i++;
        Thread.sleep(sleepTime);
    }

    if (!hasResults)
        throw new NotResultEcxeption(); //for exapmle, throw exception if task was not finished 

    Object result = service.getTaskResult(taskId);
    return result;
}
...

我想问你一下建议:这种模式解决方案好吗?是否使用Thread.sleep()定期检查任务结果?或者您可以建议一些框架以获得更好的解决方案吗?

2 个答案:

答案 0 :(得分:1)

通常,答案是:它取决于。

这实际上取决于您使用的服务的确切性质。如果那个东西只有推动工作的界面;然后按id查询;然后你的代码“几乎”可以做什么。从这个意义上说,是唯一的选择。您可以在代码中进一步分离关注点/责任(例如,通过让线程A永远轮询到仅在结果可用时停止;以及另一个线程B,检查A是否仍然存在于将来的某个定义点,然后杀死它)。

如果您的服务还具有推送您的代码的方法,那么另一种选择是;换句话说,调用一个回调方法;然后事情就不同了。

答案 1 :(得分:1)

对于可能发生的某些事件,异步任务应该有某种listeners列表。如果是这样,那么你应该wait在异步调用中的某个锁定对象和notify在调用listener时锁定。 否则,您必须使用pulling设计(使用Thread.sleep)。