Spring Boot 비동기 호출@Async 프로 세 스 상세 설명

실제 개발 에서 가끔 은 요청 을 신속하게 처리 하고 응답 하기 위해 우 리 는 여러 가지 임 무 를 동시에 수행 하거나 메 인 임 무 를 먼저 처리 할 수 있 습 니 다.즉,비동기 호출,비동기 호출 의 실현 이 많 습 니 다.예 를 들 어 다 중 스 레 드,정시 임무,메시지 대기 열 등 입 니 다.
@Async 비동기 방법 호출 에 대해 말씀 드 리 겠 습 니 다.
1.@Async 사용 데모
@Async 는 Spring 내 장 된 주석 으로 비동기 작업 을 처리 하 는 데 사 용 됩 니 다.SpringBoot 에 도 적용 되 며,SpringBoot 프로젝트 에 서 는 boot 자체 의 starter 를 제외 하고 추가 로 의존 을 도입 할 필요 가 없습니다.
@Async 를 사용 하려 면 시작 클래스 에@EnableAsync 주동 성명 을 추가 하여 비동기 방법 을 열 어야 합 니 다.

@EnableAsync
@SpringBootApplication
public class SpringbootApplication {

  public static void main(String[] args) {
    SpringApplication.run(SpringbootApplication.class, args);
  }
}
현재 3 개의 작업 을 처리 해 야 합 니 다.각각 AsyncTask 류 의 taskOne,taskTwo,taskThree 방법 에 대응 합 니 다.여 기 는 스 레 드 sleep 를 만들어 실제 운행 을 모 의 합 니 다.

@Slf4j
@Component
public class AsyncTask {

  private Random random = new Random();
  
  public void taskOne() throws InterruptedException {
    long start = System.currentTimeMillis();
    Thread.sleep(random.nextInt(10000));
    long end = System.currentTimeMillis();
    log.info("         {} ", (end - start)/1000f);
  }
  
  public void taskTwo() throws InterruptedException {
    long start = System.currentTimeMillis();
    Thread.sleep(random.nextInt(10000));
    long end = System.currentTimeMillis();
    log.info("         {} ", (end - start)/1000f);
  }
  
  public void taskThree() throws InterruptedException {
    long start = System.currentTimeMillis();
    Thread.sleep(random.nextInt(10000));
    long end = System.currentTimeMillis();
    log.info("         {} ", (end - start)/1000f);
  }
}
그리고 테스트 클래스 를 작성 합 니 다.@Async 주 해 는 Spring 용기 가 시 작 된 후에 야 유효 하기 때문에 테스트 클래스 는 SpringBoot 의 test 패키지 에 넣 고 SpringBootTest 를 사 용 했 습 니 다.

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootApplication.class)
public class AsyncTaskTest {

  @Autowired
  private AsyncTask asyncTask;

  @Test
  public void doAsyncTasks(){
    try {
      long start = System.currentTimeMillis();
      asyncTask.taskOne();
      asyncTask.taskTwo();
      asyncTask.taskThree();
      Thread.sleep(5000);
      long end = System.currentTimeMillis();
      log.info("         {} ", (end - start)/1000f);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

}
테스트 방법 을 실행 하면 콘 솔 에서 작업 을 볼 수 있 습 니 다.하나,둘,셋 은 순서대로 실 행 됩 니 다.마지막 으로 메 인 프로그램 이 완 료 됩 니 다.이것 은 우리 가 예상 한 것 과 같 습 니 다.우 리 는 추가 적 인 처리 가 없 기 때문에 그들 은 일반적인 방법 입 니 다.인 코딩 순서에 따라 순서대로 실 행 됩 니 다.

작업 을 동시에 수행 하려 면 작업 방법 에@Async 주 해 를 사용 하면 됩 니 다.@Async 가 수정 한 방법 을 static 형식 으로 정의 하지 마 십시오.이 보 호출 은 유효 하지 않 습 니 다.

@Slf4j
@Component
public class AsyncTask {

  private Random random = new Random();

  //@Async           static  ,          
  @Async
  public void taskOne() throws InterruptedException {
    long start = System.currentTimeMillis();
    Thread.sleep(random.nextInt(10000));
    long end = System.currentTimeMillis();
    log.info("         {} ", (end - start)/1000f);
  }

  @Async
  public void taskTwo() throws InterruptedException {
    long start = System.currentTimeMillis();
    Thread.sleep(random.nextInt(10000));
    long end = System.currentTimeMillis();
    log.info("         {} ", (end - start)/1000f);
  }

  @Async
  public void taskThree() throws InterruptedException {
    long start = System.currentTimeMillis();
    Thread.sleep(random.nextInt(10000));
    long end = System.currentTimeMillis();
    log.info("         {} ", (end - start)/1000f);
  }

}
그 다음 에 우 리 는 테스트 클래스 를 실행 하고 있 습 니 다.이 럴 때 출력 은 다양 할 수 있 습 니 다.임 의 작업 이 먼저 실 행 될 수도 있 고 메 인 프로그램 이 닫 혀 서 출력 이 없 을 수도 있 습 니 다.

2.Future 비동기 실행 결과 획득
위 에서@Async 를 보 여 주 었 습 니 다.그러나 가끔 은 작업 의 병행 스케줄 이 필요 한 것 을 제외 하고 우 리 는 작업 의 반환 값 을 가 져 와 야 합 니 다.그리고 여러 작업 을 수행 한 후에 메 인 임 무 를 끝내 야 합 니 다.이 럴 때 어떻게 처리 해 야 합 니까?
다 중 스 레 드 에서 Callable 과 Future 를 통 해 반환 값 을 얻 을 수 있 습 니 다.이것 도 유사 합 니 다.우 리 는 Future 반환 방법 을 사용 한 실행 결과 입 니 다.AsyncResult 는 Future 의 실현 클래스 입 니 다.

@Slf4j
@Component
public class FutureTask {

  private Random random = new Random();

  //@Async           static  ,          
  @Async
  public Future<String> taskOne() throws InterruptedException {
    long start = System.currentTimeMillis();
    Thread.sleep(random.nextInt(10000));
    long end = System.currentTimeMillis();
    log.info("         {} ", (end - start)/1000f);
    return new AsyncResult <>("   Ok");
  }

  @Async
  public Future<String> taskTwo() throws InterruptedException {
    long start = System.currentTimeMillis();
    Thread.sleep(random.nextInt(10000));
    long end = System.currentTimeMillis();
    log.info("         {} ", (end - start)/1000f);
    return new AsyncResult <>("   OK");
  }

  @Async
  public Future<String> taskThree() throws InterruptedException {
    long start = System.currentTimeMillis();
    Thread.sleep(random.nextInt(10000));
    long end = System.currentTimeMillis();
    log.info("         {} ", (end - start)/1000f);
    return new AsyncResult <>("   Ok");
  }
}
AsyncResult 에서:
  • isDone()방법 은 비동기 방법 이 완성 되 었 는 지 판단 하 는 데 사용 할 수 있 으 며,작업 이 완료 되면 true
  • 로 돌아 갑 니 다.
  • get()방법 은 작업 수행 후 돌아 오 는 결 과 를 얻 는 데 사용 할 수 있 습 니 다
  • cancel(boolean mayInterruptiIfRunning)은 작업 을 취소 하 는 데 사용 할 수 있 습 니 다.인자 mayInterruptiIfRunning 은 실행 중인 작업 을 취소 할 수 있 는 지 여 부 를 표시 합 니 다.true 를 설정 하면 실행 중인 작업 을 취소 할 수 있 음
  • isCanceled()방법 은 작업 이 취소 되 었 는 지 여 부 를 나타 내 며,작업 이 정상적으로 완료 되 기 전에 취소 되 었 으 면 true
  • 로 돌아 갑 니 다.
  • get(long timeout,TimeUnit unit)은 실행 결 과 를 가 져 오 는 데 사 용 됩 니 다.지정 한 시간 내 에 결 과 를 얻 지 못 하면 null
  • 로 돌아 갑 니 다.
    
    @Slf4j
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = SpringbootApplication.class)
    public class AsyncTaskTest {
    
      @Autowired
      private FutureTask futureTask;
    
      @Test
      public void doFutureTasks(){
        try {
          long start = System.currentTimeMillis();
          Future <String> future1 = futureTask.taskOne();
          Future <String> future2 = futureTask.taskTwo();
          Future <String> future3 = futureTask.taskThree();
          //3               
          do {
            Thread.sleep(100);
          } while (future1.isDone() && future2.isDone() && future3.isDone());
          log.info("          :{}", future1.get());
          Thread.sleep(5000);
          long end = System.currentTimeMillis();
          log.info("         {} ", (end - start)/1000f);
        } catch (InterruptedException e) {
          e.printStackTrace();
        } catch (ExecutionException e) {
          e.printStackTrace();
        }
      }
    }
    테스트 클래스 를 실행 하면 작업 1,2,3 비동기 가 실 행 된 것 을 볼 수 있 습 니 다.주 작업 은 마지막 에 실 행 됩 니 다.그리고 작업 의 반환 정 보 를 얻 을 수 있 습 니 다.

    원본 주소:https://github.com/imyanger/springboot-project/tree/master/p23-springboot-async
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기