java.util.concurrent中主要包括三类工具,Executor Freamework,并发集合(Concurrent Collection),以及同步器(Synchronizer)。
Future接口表示异步计算的结果。计算完成后只能使用 get 方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消则由 cancel 方法来执行。还提供了其他方法,以确定任务是正常完成还是被取消了。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明 Future<?> 形式类型、并返回 null 作为底层任务的结果。
public class AsyncClientHttpExchange {
public static void main(final String[] args) throws Exception {
// 默认的配置
CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
try {
httpclient.start();
HttpGet request = new HttpGet("http://www.apache.org/");
Future<HttpResponse> future = httpclient.execute(request, null);
// 获取结果
HttpResponse response = future.get();
System.out.println("Response: " + response.getStatusLine());
System.out.println("Shutting down");
} finally {
httpclient.close();
}
System.out.println("Done");
}
}
同步器(Synchronizer)是一些使线程能够等待另一个线程的对象,允许它们协作。
最常用的同步器是CountDownLatch和Semaphore。较不常用的是CyclicBarrier和Exchanger。Semaphore类是一个计数信号量。计数信号量由一个指定数量的 "许可" 初始化。每调用一次 acquire(),一个许可会被调用线程取走。每调用一次 release(),一个许可会被返还给信号量。因此,在没有任何 release() 调用时,最多有 N 个线程能够通过 acquire() 方法,N 是该信号量初始化时的许可的指定数量。这些许可只是一个简单的计数器。
CountDownLatch是一个同步辅助类,以一个给定的数量初始化。countDown() 每被调用一次,这一数量就减一。通过调用 await() 方法之一,线程可以阻塞等待这一数量到达零。
下面是异步请求一组url的例子,利用callback借口完成独立的操作。
public class AsyncClientHttpExchangeFutureCallback {
public static void main(final String[] args) throws Exception {
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(3000).setConnectTimeout(3000).build();
CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
.setDefaultRequestConfig(requestConfig).build();
try {
httpclient.start();
final HttpGet[] requests = new HttpGet[] {
new HttpGet("http://www.apache.org/"),
new HttpGet("https://www.verisign.com/"),
new HttpGet("http://www.google.com/"),
new HttpGet("http://www.baidu.com/") };
final CountDownLatch latch = new CountDownLatch(requests.length);
for (final HttpGet request : requests) {
httpclient.execute(request, new FutureCallback<HttpResponse>() {
// 无论完成还是失败都调用countDown()
@Override
public void completed(final HttpResponse response) {
latch.countDown();
try {
String content = EntityUtils.toString(response.getEntity, "UFT-8");
System.out.println("response content is " + content);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(request.getRequestLine() + "->"
+ response.getStatusLine());
}
@Override
public void failed(final Exception ex) {
latch.countDown();
System.out.println(request.getRequestLine() + "->" + ex);
}
@Override
public void cancelled() {
latch.countDown();
System.out.println(request.getRequestLine()
+ " cancelled");
}
});
}
latch.await();
System.out.println("Shutting down");
} finally {
httpclient.close();
}
System.out.println("Done");
}
}
http://www.linuxidc.com/Linux/2014-09/106563.htm