0

我正在编写一个需要从某些 Web 服务异步获取数据的 Java API。API 需要具有可移植性,能够在常规 Java SE、Java EE、Android 和 BlackBerry 应用程序中使用,因此我想使用一些本机 Java API 来实现这一点(为了可移植性)。我正在考虑使用 Runnable 接口将每个请求作为单独的线程分派,但我没有太多线程经验,我意识到你需要知道你在做什么才能正确地完成它。

使用 Java 异步完成此功能的最佳方法是什么?

4

2 回答 2

1

您可能想使用 aCachedThreadPoolFixedThreadPoolin java.util.concurrent。您将希望将 a 与 aCallable一起使用Future,而不是Runnable因为您希望从 Web 服务调用返回一个值。

一个非常简单的例子:

public class MyAPI {
    public class SomeResponse {
        int value; // assumes some very basic service returns {"value":123}
    }
    // assumes spring 3+
    @Autowired RestTemplate restTemplate;

    ExecutorService pool = ExecutorService.newCachedThreadPool();

    Future<SomeResponse> getData(int someId) {
        return cachedThreadPool.submit(new Callable() {
            public SomeResponse call() {
                return restTemplate.getForObject("http://example.com/some/path/{someId}",SomeResponse.class, someId);
            }
        });
    }
}

此类服务的调用者可以.get()针对未来进行调用以获得未来结果。

于 2013-07-12T15:22:20.417 回答
1

你的异步边界在哪里?在代码中,还是在网络中?

如果在代码中,请查看java.util.concurrent.CompletionService. 这ExecutorCompletionService将使您在满足许多需求的过程中走得更远。

如果在网络中,您需要为网络请求获取一个 ID,并在稍后使用该 ID 来获取响应。代码中的实际实现并不重要。

如何获得响应?它会被轮询,还是会触发回调?

如果它被轮询,则让请求者检查(可能多次)结果。当它可用时,你就拥有了。

如果是回调,则添加一个接口(不是java关键字,典型的英文用法),完成服务可以在不知道对象细节的情况下使用。让请求者包含(作为请求的一部分)必要的信息,以便用结果回叫请求者。

如果轮询,客户端应该阻塞还是忙等待?通常,阻塞是首选以节省 CPU 资源,但是当无法唤醒请求时Thread(可能是由于它位于不同的机器上),忙碌等待可能是合乎逻辑的选择。如果您确实忙于等待,请负责任地这样做。每隔一秒左右就让 CPU 内核休眠,这种情况是非常罕见的,当问题不允许这样的中断时,如果没有它,你会增加电费,导致与机器中的其他程序不必要的争用,并且通常是一个电脑中的坏邻居。

于 2013-07-12T15:52:21.727 回答