
동기 방식은 하나의 작업이 완전히 끝날 때까지 다음 작업이 시작되지 않는 방식이다. 마치 한 줄로 서서 차례대로 처리되는 은행 업무와 같다.
예시: 음식점에서 주문을 받는 직원이 한 명뿐인 상황
1. 첫 번째 손님의 주문을 받고 음식을 준비한다
2. 음식이 완성되어 손님에게 전달될 때까지 다른 손님은 기다린다
3. 첫 번째 손님의 일이 모두 끝나면 두 번째 손님의 주문을 받는다
비동기 방식은 하나의 작업을 시작한 후, 그 작업이 끝나기를 기다리지 않고 다른 작업을 동시에 진행하는 방식이다. 여러 창구가 동시에 운영되는 은행과 같은 개념이다.
예시: 패스트푸드점의 주문 시스템
1. 계산대에서 주문을 받는다
2. 주문을 주방에 전달하고 바로 다음 손님의 주문을 받는다
3. 주방에서는 독립적으로 음식을 준비한다
4. 음식이 완성되면 번호를 불러 손님이 가져간다
장점
단점
장점
단점
동기/비동기와 함께 자주 언급되는 개념이 Blocking/Non-blocking이다.
동기/비동기: "작업의 완료 시점에 대한 관심사"
Blocking/Non-blocking: "제어권의 반환 시점"
Spring Framework에서 제공하는 @Async 어노테이션은 메서드를 비동기로 실행할 수 있게 해주는 강력한 도구이다.
핵심 원리:
간단한 예시
@Service
public class NotificationService {
// 동기 방식 - 이메일 발송이 끝날 때까지 대기
public void sendEmailSync(String email) {
// 3초가 걸리는 이메일 발송
emailSender.send(email);
System.out.println("이메일 발송 완료");
}
// 비동기 방식 - 이메일 발송을 백그라운드에서 처리
@Async
public void sendEmailAsync(String email) {
// 3초가 걸리는 이메일 발송 (별도 스레드에서 실행)
emailSender.send(email);
System.out.println("이메일 발송 완료");
}
}
사용 시나리오:
@EnableAsync
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Service
public class EmailService {
@Async
public CompletableFuture<String> sendEmail(String to, String subject) {
// 이메일 발송 로직 (시간이 오래 걸리는 작업)
try {
Thread.sleep(3000); // 3초 시뮬레이션
return CompletableFuture.completedFuture("이메일 발송 완료");
} catch (InterruptedException e) {
return CompletableFuture.failedFuture(e);
}
}
}
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean(name = "emailExecutor")
public Executor emailExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(3); // 기본 스레드 수
executor.setMaxPoolSize(10); // 최대 스레드 수
executor.setQueueCapacity(100); // 대기열 크기
executor.setThreadNamePrefix("Email-");
executor.initialize();
return executor;
}
}