关于异步调用
2013-07-26 18:29 idkkk 阅读(475) 评论(0) 编辑 收藏 举报相信有多年编程经验的老鸟都明白,同步与异步的区别,这里只谈异步的使用,不谈为何使用异步,以及何时使用异步,好,让咱们步入正题。
谈到异步就不能不说起多线程,多线程的含义举个现实中的例子,很容易理解:传统的程序一般都是按照时序一步步执行的,比如:起床->穿衣服->洗脸,每一件事情完成后才去继续下一件事情;
如果这中间穿插开电视听新闻,其实是可以充分使用多线程并发的优势的,开着电视,然后去刷牙洗脸,新闻是可以继续听的,多线程说的通俗一点就是同一时间点做N件事。
对于多线程编程在CPU内核越来越多的情况下变得越来越重要,对于Java有本并发编程的圣经 - “Java并发编程实践”可以好好参读,该书作者之一就有著名的Doug Lea,相信有童鞋使用过JDK5之前的concurrent包,在JDK5之后纳入到内置包中,从此并发编程变得简单。
在JDK5以前,多线程编程是一件相当痛苦的事情,Thread,Runnable,还需要各种wait(),notify(),稍有差池多线程并发的引起的问题,很难定位,而且不好解决及再现;到JDK5内置并发编程包后一定程度上解决了并发编程的一些痛苦,但是相对于函数式语言(erlang,scala)那么简单的并发编程无需考虑锁,还差的实在太远。
下面是使用JDK5的java.util.concurrent包的类实现多线程并发的例子:
....
private static ExecutorService executorService = Executors.newFixedThreadPool(100); long start = System.currentTimeMillis(); for (int i = 0; i < 200; i++) { executorService.execute(new RequestTask()); } executorService.shutdown(); System.out.println("总耗时" + (System.currentTimeMillis() - start) + "ms."); ....
class RequestTask implements Runnable { public void run() { System.out.println("当前时间" + System.currentTimeMillis()); }
下面是使用twitter的finagle来实现异步编程调用客户端的例子:
long start = System.currentTimeMillis(); Service<HttpRequest, HttpResponse> httpClient = ClientBuilder.safeBuild(ClientBuilder.get() .codec(Http.get()) .hosts("192.168.1.100:80") .hostConnectionLimit(100) .tcpConnectTimeout(Duration.apply(1, TimeUnit.SECONDS)) .retries(2) .logger(logger)); HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/user/list"); request.setHeader("Host", "192.168.1.100"); Future<HttpResponse> futureResponse = httpClient.apply(request).addEventListener( new FutureEventListener<HttpResponse>() { public void onSuccess(HttpResponse response) { logger.info("SUCCESS: " + response.getContent().toString(CharsetUtil.UTF_8)); } public void onFailure(Throwable cause) { logger.info("FAILURE: " + Throwables.getStackTraceAsString(cause)); } }); httpClient.close(); Await.ready(futureResponse); logger.info("耗时" + (System.currentTimeMillis() - start) + "ms.");
异步编程其实相当简单,只能感叹finagle实在是太强大了,比想象中强大的多得多。
对于JDK7的Fork/Join还没使用过,有这方面经验的可以分享下。