【问题标题】:How to properly call asyncronous service witin syncronous method如何在同步方法中正确调用异步服务
【发布时间】:2016-12-09 14:11:35
【问题描述】:

我是客户,使用服务。

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

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() 定期检查任务结果是一种好习惯吗?或者您可以建议一些框架以获得更好的解决方案?

【问题讨论】:

    标签: java asynchronous design-patterns service


    【解决方案1】:

    通常,答案是:视情况而定。

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

    如果您的服务也有方法推送您的代码,则另一种选择是;换句话说,invoke 是一个 callback 方法;那么事情就不同了。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-01
        • 1970-01-01
        相关资源
        最近更新 更多