동기 프로그래밍 (Synchronous)
- 작업의 실행 흐름은 순차적으로 동작
- 코드를 파악하기 쉽고 결과를 쉽게 예측 가능하므로 디버깅이 쉬움
- 특정 작업 중 다른 작업을 할 수 없다는 단점
비동기 프로그래밍 (Asynchronous)
- 작업의 실행 흐름은 기본적으로 순차적이지 않음
- 현재 실행 중인 작업 이외에 다른 작업 가능.
- 클라이언트, 서버 등 모든 환경에서 유용하게 사용 가능
- 대표적으로 CallBack, Promise, Future, Coroutine 등이 있다.
비동기 프로그래밍 구현 방식 - Kotlin
Thread
- 가장 기본이 되는 방식
- Runnable 인터페이스를 구현하여 구현
- 하나의 스레드 - 싱글 스레드, 다중 스레드 - 멀티스레드
fun main() {
for (i in 0..5) {
val thread = Thread{
println("current-thread-name : ${Thread.currentThread().name}")
}
thread.start()
}
}
// 실행 시 결과가 매번 다름
- 스케줄링 알고리즘에 의해 스레드가 전환되는 작업을 컨텍스트 스위칭이라 한다.
- OOM 이 터질 우려가 있다. 응답 지연이 발생할 가능성이 있다.
- Thread Pool 을 생성하여 안전하게 해결 가능
fun main() {
val pool: ExecutorService = Executors.newFixedThreadPool(5)
try {
for (i in 0..5) {
pool.execute {
println("current-thread-name : ${Thread.currentThread().name}")
}
}
} finally {
pool.shutdown()
}
println("current-thread-name : ${Thread.currentThread().name}")
}
=> 스레드 풀을 생성한 모습
Future
- 비동기 작업에 대한 결과를 얻고 싶은 경우 사용
- 다른 작업을 병행하며 수행할 경우 유용
- Runnable 말고 Callable 을 사용하여 결과를 얻을 수 있다.
- get 함수는 무한정 대기, 타임 아웃까지 블로킹 된다는 단점
- 동시에 실행 되는 다중 비동기 작업에 대한 결과를 하나로 조합하여 처리하지 못함.
fun sum(a: Int, b: Int) = a + b
fun main() {
val pool = Executors.newSingleThreadExecutor()
val future = pool.submit(Callable {
sum(100, 200)
})
println(" 작업 시작 ")
val futureResult = future.get() // . println(futureResult)
println(" 작업 완료 ")
}
Completable Future
- Future의 단점을 극복하기 위해 JDK 8 부터 나옴
- get을 사용할 경우 블로킹이 된다.
fun main() {
val completableFuture = CompletableFuture.supplyAsync {
Thread.sleep(2000)
sum(100, 200)
}
println(" 작업 시작 ")
//completableFuture.thenApplyAsync(::println)
while (!completableFuture.isDone) {
Thread.sleep(500)
println(" 작업 결과 집계 중.")
}
println(" 작업 종료. ")
}
// thenApplyAsync를 통해 논블로킹 동작, 별도의 스레드 풀 지정 가능
// isDone은 작업 완료인지 체크
// isCancelled 를 통해 취소 상태 체크, 작업 도중 에러 발생 상태를 체크하는 isCompletedExceptionally
=> 대다수의 비동기 처리에서 유용하게 사용 가능하다.
=> 대다수의 API를 호출하고 결과를 결합 후 응답하는 시나리오에서 매우 유용함!
반응형
'📕 Spring Framework > Spring 개념 정리' 카테고리의 다른 글
Spring boot multi datasource 등록 시 주의 사항 (0) | 2024.09.18 |
---|---|
[Spring data JPA] N+1 문제 해결 (2) | 2023.02.28 |
[@DataJpaTest] h2 인메모리 db를 이용한 테스트 설정 방법 (0) | 2022.12.21 |
WebFlux는 무엇이고, 왜 나왔고, 언제 쓰이는가? (0) | 2022.08.31 |
Spring Security [2] - 예외 처리 AuthenticationEntryPoint & AccessDeniedHandler (0) | 2022.08.21 |