在java中等待异步http请求
问题描述:
我使用Jetty HTTP客户端异步发出约50个HTTP调用。代码看起来像这样:在java中等待异步http请求
List<Address> addresses = getAddresses();
final List<String> done = Collections.synchronizedList(new LinkedList<String>());
List<ContentExchange> requests;
for (Address address : addresses) {
ContentExchange ce = new ContentExchange() {
@Override
protected void onResponseComplete() throws IOException {
//handle response
done.add("done");
}
}
ce.setURL(createURL(address));
requests.add(ce);
}
for (ContentExchange ce : requests) {
httpClient.send(ce);
}
while (done.size() != addresses.size()) {
Thread.yield();
}
System.out.println("All addresses processed");
它调用一个休息服务,返回一些关于地址的数据。我期望它做的是这样的:
- 使50个异步(非阻塞)http调用。
- 该线程将等待所有50个完成。
但是,它不工作。如果我没有while循环,它工作正常,但我需要等到所有50个完成。有什么方法可以等到全部50完成?
另外我知道有关ExecutorService和多线程解决方案,但我需要一个单线程解决方案与非阻塞IO。
答
使用java.util.concurrent.CountDownLatch
来管理这个。
实施例从Eclipse Jetty 8.1.10.v20130312's Siege.java测试类:
final CountDownLatch latch = new CountDownLatch(concurrent);
for (int i=0;i<concurrent;i++)
{
ConcurrentExchange ex = new ConcurrentExchange(client,latch,uris,repeats);
if (!ex.next()) // this executes the client.send()
{
latch.countDown(); // count down if client.send() was in error
}
}
latch.await(); // wait for all ConcurrentExchange's to complete (or error out)
注:ConcurrentExchange是内Siege.java的私有类。
在HttpExchange
对象
然后,使用CountDownLatch.countDown()
拨打以下方法
- onConnectionFailed(Throwable x) - example
- onException(Throwable x) - 例如
- onExpire() - 例如
- onResponseComplete() - 例如
请注意,所有示例都使用AtomicBoolean counted
来确保它们只计算一次。
if (!counted.getAndSet(true)) // get the value, then set it to true
{
// only get here if counted returned false. (and that will only happen once)
latch.countDown(); // count down this exchange as being done.
}
谢谢,使用CountDownLatch工作 – cpprototypes 2013-05-03 00:37:24