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