비동기 호출과 동기 호출
동기 호출: 순차적으로 실행하고, 호출로 결과를 반환하고, 다음 호출을 다시 실행
비동기 호출: 기다리지 않고 다음 호출을 실행합니다. 반환될 결과
@Async의 주석 코드는 다음과 같습니다.
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Async { String value() default ""; }
Annotation은 유형 및 메소드에서 사용할 수 있습니다.
값은 값으로 정의되며 기본값은 비어 있습니다
일반적으로 이 주석은 @EnableAsync 와 일치해야 하며 원본 코드는 다음과 같습니다
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({AsyncConfigurationSelector.class}) public @interface EnableAsync { Class<? extends Annotation> annotation() default Annotation.class; boolean proxyTargetClass() default false; AdviceMode mode() default AdviceMode.PROXY; int order() default Integer.MAX_VALUE; }
구성 시작을 위해 이 주석을 통해 주로 시작 클래스에 배치됩니다.
시작 클래스에 다음을 추가합니다.
@SpringbootApplication @EnableAsync public class Application{ public static void main(String[] args){ SrpingApplication.run(Application.class, args); } }
함수 결과는 호출부터 반환까지만 실행할 수 있습니다. 동기 호출이라고 하는 한 단계
서비스 레이어 코드:
public class Service{ public void test01() throws InterruptedException{ Thread.sleep(5000); System.out.println("保存日志"); } }
제어 레이어 코드 모듈:
public class Controler{ @Autowired private Service service; @GetMapping("/test") public String getTest(){ try{ System.out.println("开始"); service.test01(); System.out.println("结束"); }catch(InterruptedException e){ e.prinStackTrace(); } } }
시작 클래스를 통해 시작한 후 springboot
출력은 다음과 같습니다.
Start
// 5초 동안 기다리는 것입니다. 터미널이 표시되거나 닫히지도 않습니다.
End
비동기 호출, 실행 함수는 반환 결과를 기다리지 않고 다음 단계를 실행하세요
서비스 레이어 코드:
이 메소드를 식별하기 위해 주로 @Async 주석을 추가합니다
public class Service{ @Async public void test01() throws InterruptedException{ Thread.sleep(500); System.out.println("保存日志"); } }
제어 레이어 코드 모듈:
서비스 레이어 함수를 호출하여 @EnableAsync를 시작
public class Controler{ @Autowired private Service service; @GetMapping("/test") public String getTest(){ try{ System.out.println("开始"); service.test01(); System.out.println("结束"); }catch(InterruptedException e){ e.prinStackTrace(); } } }
그리고 시작 클래스에 주석 추가
@SpringbootApplication @EnableAsync public class Application{ public static void main(String[] args){ SrpingApplication.run(Application.class, args); } }
스레드 풀에 대한 기본 지식은 이전 기사를 참조하세요.
Java에서 스레드 및 스레드 풀을 올바르게 닫는 방법(코드 연습에는 소스 코드가 포함됨) 분석)
Java 스레드 풀 생성 방법 상세 분석(전체)
스레드 풀을 지정하지 않으면 기본으로 사용되는 스레드 풀은 SimpleAsyncTaskExecutor입니다(작업이 오면 그냥 스레드를 생성하면 됩니다. 계속해서 스레드를 생성하면 CPU가 너무 높아서 OOM이 발생함). 내장 스레드 풀에는 일반적으로 단점이 있습니다. 일반적으로 ThreadPoolExecutor를 사용하는 것이 좋습니다(스레드 풀의 리소스를 지우고 위험을 피하세요)
자세한 내용은 다음과 같습니다.
@Async 이 주석은 다음을 찾습니다. AsyncConfigurer 인터페이스(구현 클래스는 AsyncConfigurerSupport, 기본 구성 및 메서드는 비어 있음), 스레드 풀을 지정하기 위해 인터페이스를 재정의할 수 있습니다.
애플리케이션에서 일부 스레드 풀 정의 .xml 변수
thread.core.size=16 thread.max.size=16 thread.queue.size=30 thread.prefix=xx-
커스텀 스레드 풀은 다음과 같습니다
import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.ThreadPoolExecutor; @Configuration public class ThreadPoolConfig { // 线程名称前缀 @Value("${thread.prefix}") private String threadPrefix; // 核心线程数 @Value("${thread.core.size}") private int coreSize; // 最大线程数 @Value("${thread.max.size}") private int maxSize; // 队列长度 @Value("${thread.queue.size}") private int queueSize; // 通过bean注解注入 @Bean("xx") public ThreadPoolTaskExecutor taskExecutor() { ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); //设置线程池参数信息 taskExecutor.setCorePoolSize(coreSize); taskExecutor.setMaxPoolSize(maxSize); taskExecutor.setQueueCapacity(queueSize); taskExecutor.setThreadNamePrefix(threadPrefix); taskExecutor.setWaitForTasksToCompleteOnShutdown(true); taskExecutor.setAwaitTerminationSeconds(30); //修改拒绝策略为使用当前线程执行 taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //初始化线程池 taskExecutor.initialize(); return taskExecutor; } }
위 내용은 Java에서 @Async에 의해 비동기적으로 호출되는 메서드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!