Future接口

Future表示一个异步计算任务的结果。

Future接口方法有:

boolean cancel(boolean mayInterruptIfRunning):取消异步运算。入参为true时,表示会取消已经开始执行的运算。为false时,不会取消已经开始执行的运算。

boolean isCancelled():

boolean isDone():任务结束的话,返回true,否则返回false。任务结束不仅仅指任务顺利完成,还包括任务抛异常、任务被取消等。

V get() throws InterruptedException, ExecutionException:在主线程中获取异步运算的结果,在获取到结果之前主线程一直阻塞。如果任务执行抛异常,则get()方法会抛出ExecutionException异常。如果任务被取消,则get()会抛出CancellationException异常。

V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException:在主线程中获取异步运算的结果,在获取到结果之前主线程阻塞,超过指定时间后会抛出TimeoutException异常。

RunnableFuture接口

RunnableFuture接口继承了Runnable接口和Future接口,但并未定义自己的方法。

FutureTask是RunnableFuture实现类。FutureTask有两个构造器:FutureTask(Callable<V> callable)和FutureTask(Runnable runnable, V result)。

TODO示例

FutureTask的run()实例方法内部是调用Runnable实例或者Callable实例的run()方法,但是是在主线程执行,而不是在异步线程执行。这j8有啥用???

ListenableFuture接口

其实ListenableFuture接口有两个,但都不是jdk自带的,guava一个,spring一个。

guava的ListenableFuture接口全类名是com.google.common.util.concurrent.ListenableFuture,继承了Future接口,只定义了一个方法:void addListener(Runnable listener, Executor executor)。常用实现类是guava的ListenableFutureTask类,全类名是com.google.common.util.concurrent.ListenableFutureTask。

spring的ListenableFuture接口在spring-core.jar包中,全类名是org.springframework.util.concurrent.ListenableFuture,继承了Future接口,定义方法如下:

void addCallback(ListenableFutureCallback<T> callback):注册一个ListenableFutureCallback实例。

void addCallback(SuccessCallback<T> successCallback, FailureCallback failureCallback):注册一个SuccessCallback实例和一个failureCallback实例。

completableFuture<T> completable():把一个spring的ListenableFuture实例转成一个jdk的CompletableFuture实例。

spring的ListenableFuture接口常用实现类是spring的ListenableFutureTask和AsyncResult。

guava ListenableFutureTask使用示例:

  1. public static void main(String[] args) {
  2. ExecutorService executorService = Executors.newCachedThreadPool();
  3. ListeningExecutorService service = MoreExecutors.listeningDecorator(executorService);
  4. long begin = System.currentTimeMillis();
  5. ListenableFuture<Boolean> booleanTask = service.submit(() -> {
  6. Thread.sleep(1000);
  7. System.out.println("1, currentThread= " + Thread.currentThread().getName());
  8. System.out.println("".substring(0, 1));
  9. return true;
  10. });
  11. booleanTask.addListener(() -> {
  12. try {
  13. booleanTask.get();
  14. Thread.sleep(2000);
  15. System.out.println("2, currentThread= " + Thread.currentThread().getName());
  16. } catch (Exception e) {
  17. System.out.println(123);
  18. // e.printStackTrace();
  19. }
  20. }, executorService);
  21.  
  22. Futures.addCallback(booleanTask, new FutureCallback<Boolean>() {
  23. @Override
  24. public void onSuccess(Boolean result) {
  25. System.out.println("3, currentThread= " + Thread.currentThread().getName() + ", booleanTask result= " + result);
  26. }
  27.  
  28. @Override
  29. public void onFailure(Throwable e) {
  30. System.out.println(234);
  31. // e.printStackTrace();
  32. }
  33. }, executorService);
  34. System.out.println("cost " + (System.currentTimeMillis() - begin) + "ms");
  35. }

利用guava的MoreExecutors工具类构造出ListeningExecutorService实例,调用此实例的submit()方法即可得到一个ListenableFuture实例。接下来可以调用ListenableFuture的addListener(Runnable listener, Executor executor)方法添加一个监听任务,但这个方法说实话,不好。为什么呢?因为addListener()方法添加的监听任务不管被监听任务是否抛异常都会执行,要是想不抛异常执行一个任务,抛异常时执行另一个任务,就要用try catch把ListenableFuture实例的get()方法包裹,然后在try子句中写不抛异常时要执行的任务,catch子句中写抛异常时要执行的任务。不如用guava提供的Futures工具类,这个工具类中提供了很多静态方法,其中addCallback(ListenableFuture<V> future, FutureCallback<V> callback, Executor executor)方法可以轻松实现ListenableFuture任务抛异常和不抛异常时监听任务的不同分支。

FluentFuture类

FluentFuture是guava提供的类,在com.google.common.util.concurrent包中,全类名是com.google.common.util.concurrent.FluentFuture。

待研究

spring ListenableFutureTask使用示例:

TODO示例

AsyncResult类

AsyncResult是spring提供的类,在spring-context.jar包中,全类名是org.springframework.scheduling.annotation.AsyncResult。AsyncResult实现了ListenableFuture接口。

AsyncResult使用示例:

  1. public static void main(String[] args) throws NoSuchAlgorithmException {
  2. AsyncResult<Number> asyncResult = new AsyncResult<>(getRandom());
  3. asyncResult.addCallback(result -> {
  4. System.out.println("result= " + result + ", currentThread= " + Thread.currentThread().getName());
  5. }, e -> {
  6. System.out.println("e= " + e.getMessage() + ", currentThread= " + Thread.currentThread().getName());
  7. }
  8. );
  9. }
  10.  
  11. private static Double getRandom() throws NoSuchAlgorithmException {
  12. SecureRandom secureRandom = SecureRandom.getInstanceStrong();
  13. return secureRandom.nextDouble();
  14. }

这下终于按照预期打印了。

CompletableFuture接口

待研究

如何通过Maven的Tomcat插件运行Web工程的更多相关文章

  1. 如何通过Maven的Jetty插件运行Web工程

    首先建议使用jetty9,因为据官方文档显示,Jetty 7 and Jetty 8 are now EOL (End of Life),如下.但是由于项目使用的版本一般都比较低,这里以jetty8为 ...

  2. (转)淘淘商城系列——使用maven tomcat插件启动web工程

    http://blog.csdn.net/yerenyuan_pku/article/details/72672138 上文我们一起学习了怎样搭建maven工程,这篇文章我就来教大家一起学习怎样用to ...

  3. 购物商城学习--第三讲(tomcat插件启动web工程)

    此处提到的tomcat插件即maven工程集成的tomcat插件,可以在添加maven的tomcat插件之后,在本地通过脚本或者命令行方式运行web工程,tomcat插件启动只需要修改一个端口即可,非 ...

  4. myeclipse maven tomcat插件 创建web工程

    自从有了云笔记,很久不写博客了.今天写了使用Freemarker静态化JSP页面,索性就发出来.初学,勿喷. 这篇文字以前放在云笔记里,当然里面有很多借鉴网络上的东西,而自己也使用Maven很久了,索 ...

  5. (转)淘淘商城系列——使用maven tomcat插件启动聚合工程

    http://blog.csdn.net/yerenyuan_pku/article/details/72672389 上文我们一起学习了如何使用maven tomcat插件来启动web工程,本文我们 ...

  6. Maven集成Tomcat插件

    目录 类似插件及版本区别: 本地运行,启动嵌入式tomcat: 错误一: 错误二: Idea运行调试: vscode运行调试: 远程部署: 项目中的pom.xml配置: Tomcat中的tomcat- ...

  7. IntelliJ IDEA配置Tomcat/Jetty运行Web项目

    一.使用Maven的POM引入插件的形式: 这种方式只需在POM中引入Tomcat/Jetty的插件即可运行.参考:http://www.cnblogs.com/EasonJim/p/6687272. ...

  8. Intellij IDEA如何使用Maven Tomcat Plugin运行web项目(转)

    首先,Run --> Edit Configurations,这时候如下图: 然后点击左上角的加号,可以添加一个新的配置,如下图: 选择Maven,如下图: 下面填上自己的配置信息,点击appl ...

  9. Intellij IDEA如何使用Maven Tomcat Plugin运行web项目

    首先,Run ——> Edit Configurations,这时候如下图: 然后点击左上角的加号,可以添加一个新的配置,如下图: 选择Maven,如下图: 下面填上自己的配置信息,点击appl ...

随机推荐

  1. Java基本知识

    一.I/O 分字节流和字符流 字节流由InputStream和OutputStream读入和写入 DataInputStream继承自FilterInputStream,可以读取基本数据类型(char ...

  2. delphi变量作用域

    完全摘自网络(一件飘雪),供参考: 很多初学者对delphi单元的变量和函数访问权限不理解,在此我举例说明,希望初学者看此文后能茅塞顿开. delphi单元的变量和函数访问权限问题如下两个单元描述: ...

  3. 洛谷-统计数字-NOIP2007提高组复赛

    题目描述 Description 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*10^9).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照 ...

  4. [转]Jmeter(一)-精简测试脚本

    通过jmeter代理录制脚本后,会产生大量的无用的请求,尽管在代理中已经过滤了一部分图片或者CSS.JS文件. 手动查看主要的请求:这里主要关注登陆请求,要确定有效的URL请求 删除除/Login.a ...

  5. 无法启动T-SQL调试。未能连接到计算机"."。这是在主机名解析时通常出现的暂时错误……

    今天在按在SSMS中,按F11进行断点调试时,弹出错误:"无法启动T-SQL调试.未能连接到计算器".".这是在主机名解析时通常出现的暂时错误--", 如下图: ...

  6. 打开新世界的第一步:学习servlet

    什么是servlet? 是用Java编写的服务器端程序.其主要功能在于交互式地浏览和修改数据,生成动态Web内容. 创建servlet 一.创建一个web project 1)流程:eclipse-F ...

  7. Json-lib用法

    Json-lib用法 1.需要的jar包有一下几个,别的文章中没有xom这个jar包,但我的工程中如果没有这个包,那么,json数据转换为xml数据的程序中在执行XMLSerializer xmlSe ...

  8. express学习点滴- session()和cookieSession()的区别

    express 里提供了两种有关session的中间件 * session() 提供了内存和数据库两种方式保存session.具体两种session原理请自行学习,不进行展开了.自己也是一知半解... ...

  9. 2016WHD.china世界云计算日·北京站即将召开

    WHD.china自进驻中国以来,已在上海.北京成功举办多届,2015年于北京举办的会议更是盛况空前,注册参会者逾800人次,汇聚了国内外众多知名云服务商.IDC商.电子商务企业.电信运营商.ISP等 ...

  10. 使用php创建WebSocket服务

    执行方法:首先先修改server.php与index.html的ip通过命令行执行 [php路径]php.exe "[文件路径]server.php"然后通过浏览器打开index. ...