wordpress不同分类不同广告 文章属于不同分类,网站 优化手机版,一天能赚100元的app,诚讯网站设计在Java应用中#xff0c;绝大多数情况下都是通过同步的方式来实现交互处理的#xff1b;但是在处理与第三方系统交互的时候#xff0c;容易造成响应迟缓的情况#xff0c;之前大部分都是使用多线程来完成此类任务#xff0c;其实#xff0c;在spring 3.x之后#xff0c;… 在Java应用中绝大多数情况下都是通过同步的方式来实现交互处理的但是在处理与第三方系统交互的时候容易造成响应迟缓的情况之前大部分都是使用多线程来完成此类任务其实在spring 3.x之后就已经内置了Async来完美解决这个问题 1. 何为异步调用 在解释异步调用之前我们先来看同步调用的定义同步就是整个处理过程顺序执行当各个过程都执行完毕并返回结果。 异步调用则是只是发送了调用的指令调用者无需等待被调用的方法完全执行完毕而是继续执行下面的流程。 例如 在某个调用中需要顺序调用 A, B, C三个过程方法如他们都是同步调用则需要将他们都顺序执行完毕之后方算作过程执行完毕 如B为一个异步的调用方法则在执行完A之后调用B并不等待B完成而是执行开始调用C待C执行完毕之后就意味着这个过程执行完毕了。 2. 常规的异步调用处理方式 在Java中一般在处理类似的场景之时都是基于创建独立的线程去完成相应的异步调用逻辑通过主线程和不同的线程之间的执行流程从而在启动独立的线程之后主线程继续执行而不会产生停滞等待的情况。或是使用TaskExecutor执行异步线程参看http://www.cnblogs.com/wihainan/p/6098970.html。 3. Async介绍 在Spring中基于Async标注的方法称之为异步方法这些方法将在执行的时候将会在独立的线程中被执行调用者无需等待它的完成即可继续其他的操作。 如何在Spring中启用Async。基于Java配置的启用方式 1 Configuration
2 EnableAsync
3 public class SpringAsyncConfig { ... } 4. 基于Async无返回值调用 使用的方式非常简单一个标注即可解决所有的问题 1 Async //标注使用
2 public void asyncMethodWithVoidReturnType() {
3 System.out.println(Execute method asynchronously.
4 Thread.currentThread().getName());
5 } 5. 基于Async返回值的调用 1 Async 2 public FutureString asyncMethodWithReturnType() { 3 System.out.println(Execute method asynchronously - Thread.currentThread().getName()); 4 try { 5 Thread.sleep(5000); 6 return new AsyncResultString(hello world !!!!); 7 } catch (InterruptedException e) { 8 // 9 }
10
11 return null;
12 } 以上示例可以发现返回的数据类型为Future类型其为一个接口。具体的结果类型为AsyncResult,这个是需要注意的地方。 调用返回结果的异步方法示例 1 public void testAsyncAnnotationForMethodsWithReturnType() 2 throws InterruptedException, ExecutionException { 3 System.out.println(Invoking an asynchronous method. Thread.currentThread().getName()); 4 FutureString future asyncAnnotationExample.asyncMethodWithReturnType(); 5 6 while (true) { ///这里使用了循环判断等待获取结果信息 7 if (future.isDone()) { //判断是否执行完毕 8 System.out.println(Result from asynchronous process - future.get()); 9 break;
10 }
11 System.out.println(Continue doing something else. );
12 Thread.sleep(1000);
13 }
14 } 这些获取异步方法的结果信息是通过不停的检查Future的状态来获取当前的异步方法是否执行完毕来实现的。 6. 基于Async调用中的异常处理机制 在异步方法中如果出现异常对于调用者caller而言是无法感知的。如果确实需要进行异常处理则按照如下方法来进行处理 1. 自定义实现AsyncTaskExecutor的任务执行器 在这里定义处理具体异常的逻辑和方式。 2. 配置由自定义的TaskExecutor替代内置的任务执行器 示例步骤1自定义的TaskExecutor 1 public class ExceptionHandlingAsyncTaskExecutor implements AsyncTaskExecutor { 2 private AsyncTaskExecutor executor; 3 public ExceptionHandlingAsyncTaskExecutor(AsyncTaskExecutor executor) { 4 this.executor executor; 5 } 6 用独立的线程来包装Async其本质就是如此 7 public void execute(Runnable task) { 8 executor.execute(createWrappedRunnable(task)); 9 }
10 public void execute(Runnable task, long startTimeout) {
11 /用独立的线程来包装Async其本质就是如此
12 executor.execute(createWrappedRunnable(task), startTimeout);
13 }
14 public Future submit(Runnable task) { return executor.submit(createWrappedRunnable(task));
15 //用独立的线程来包装Async其本质就是如此。
16 }
17 public Future submit(final Callable task) {
18 //用独立的线程来包装Async其本质就是如此。
19 return executor.submit(createCallable(task));
20 }
21
22 private Callable createCallable(final Callable task) {
23 return new Callable() {
24 public T call() throws Exception {
25 try {
26 return task.call();
27 } catch (Exception ex) {
28 handle(ex);
29 throw ex;
30 }
31 }
32 };
33 }
34
35 private Runnable createWrappedRunnable(final Runnable task) {
36 return new Runnable() {
37 public void run() {
38 try {
39 task.run();
40 } catch (Exception ex) {
41 handle(ex);
42 }
43 }
44 };
45 }
46 private void handle(Exception ex) {
47 //具体的异常逻辑处理的地方
48 System.err.println(Error during Async execution: ex);
49 }
50 } 分析 可以发现其是实现了AsyncTaskExecutor, 用独立的线程来执行具体的每个方法操作。在createCallable和createWrapperRunnable中定义了异常的处理方式和机制。 handle()就是未来我们需要关注的异常处理的地方。 配置文件中的内容 1 task:annotation-driven executorexceptionHandlingTaskExecutor schedulerdefaultTaskScheduler /
2 bean idexceptionHandlingTaskExecutor classnl.jborsje.blog.examples.ExceptionHandlingAsyncTaskExecutor
3 constructor-arg refdefaultTaskExecutor /
4 /bean
5 task:executor iddefaultTaskExecutor pool-size5 /
6 task:scheduler iddefaultTaskScheduler pool-size1 / 7. Async调用中的事务处理机制 在Async标注的方法同时也适用了Transactional进行了标注在其调用数据库操作之时将无法产生事务管理的控制原因就在于其是基于异步处理的操作。 那该如何给这些操作添加事务管理呢可以将需要事务管理操作的方法放置到异步方法内部在内部被调用的方法上添加Transactional. 例如 方法A使用了Async/Transactional来标注但是无法产生事务控制的目的。 方法B使用了Async来标注 B中调用了C、DC/D分别使用Transactional做了标注则可实现事务控制的目的。 不积跬步无以至千里 转载于:https://www.cnblogs.com/zhangwufei/p/10036401.html