乐趣区

关于springboot:spring-boot异步方法Async踩坑

前言

我的需要是创立一个新线程来执行一些操作,因为如果用同一个线程就会导致资源始终被占据,影响响应效率。

异步的概念

我的了解:异步即为在多辆车在多条路上行驶,同步即为多辆车在一条路上行驶。举个栗子:同步:以后如果正在学习 c 语言的话,那么咱们依照课程安顿是不应该学习 c ++ 的,只有等这个学期结束学完 c 语言,下个学期能力学习 c ++。异步:离散数学和 c 语言都是在本学期学习,你不用等 c 语言学完再学离散数学。

spring boot 如何实现异步

Google 搜寻发现存在异步的注解。

How To Do @Async in Spring




@Async
public void asyncMethodWithVoidReturnType() {
    System.out.println("Execute method asynchronously." 
      + Thread.currentThread().getName());
}

总结:1. 开启异步反对 2. 异步注解应用留神 3. 异步示例

我的异步踩坑

1. 未仔细阅读two limitations:Self-invocation — won’t work.

测试代码如下:

public class AsyncTest {
  @Test
  public void test1() {System.out.println("test1 的线程 id 为:" + Thread.currentThread().getId());
    test2();}
  
  @Async
  public void test2() {System.out.println("test2 的线程 id 为:" + Thread.currentThread().getId());
  }
}

成果:两个都是同一个线程,并没有达到 test2 是独立的线程的成果

解决方案:将 test2 放到另一个 class 中,自我调用将不会失效。

2. 必须为 @Component 或 @Service 注解能力使 @Async 失效

在将异步办法放到其余类:

// 第一个类
public class AsyncTest1 {public void test1() {System.out.println("test1 的线程 id 为:" + Thread.currentThread().getId());
    // 新建一个 AsyncTest2 类,调用其异步办法
    AsyncTest2 asyncTest2 = new AsyncTest2();
    asyncTest2.test2();}
}

// 第二个类,定义异步办法
public class AsyncTest2 {
  @Async
  public void test2() {
    System.out.println("test2 的线程 id 为:" + 
        Thread.currentThread().getId());
  }
}

But:后果不随我愿,仍然是打印显示是同一线程。

解决:

Spring creates a proxy for each service and component you create using the common annotations. Only those proxies contain the wanted behavior defined by the method annotations such as the Async. So, calling those method not via the proxy but by the original naked class would not trigger those behaviors.
简言之:spring 将会给用 @Component 和 @Service的类发明代理,只有领有代理的类能力在应用 @Async 时失去想要的后果。

退出移动版