2013-05-01 263 views
1

我使用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"); 

它調用一個休息服務,返回一些關於地址的數據。我期望它做的是這樣的:

  1. 使50個異步(非阻塞)http調用。
  2. 該線程將等待所有50個完成。

但是,它不工作。如果我沒有while循環,它工作正常,但我需要等到所有50個完成。有什麼方法可以等到全部50完成?

另外我知道有關ExecutorService和多線程解決方案,但我需要一個單線程解決方案與非阻塞IO。

回答

2

使用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()撥打以下方法

請注意,所有示例都使用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. 
} 
+0

謝謝,使用CountDownLatch工作 – cpprototypes 2013-05-03 00:37:24