Runnable 인터페이스
Runnable 인터페이스는 매우 단순합니다. 단 하나의 메서드, void run()을 정의하며, 이 메서드는 반환 값도, 예외도 없습니다. 이는 Runnable이 작업 실행의 단순함을 반영하며, 실행 결과나 오류를 직접 반환하지 않습니다. 결과적으로, Runnable 구현체는 별도의 로직(예: 공유 객체를 통한 결과 저장)을 통해 결과를 관리해야 할 수도 있습니다.
Runnable은 직접적으로 스레드를 생성하고 실행할 때, 혹은 Executor Framework를 사용하여 스레드 풀에 작업을 제출할 때 사용됩니다.
public class RunnableExample implements Runnable {
@Override
public void run() {
// 실행하고자 하는 작업
System.out.println("Hello from Runnable thread!");
}
public static void main(String[] args) {
Runnable runnableTask = new RunnableExample();
Thread thread = new Thread(runnableTask);
thread.start();
}
}
Callable 인터페이스
Callable 인터페이스는 Runnable보다 복잡한 작업 실행을 위해 설계되었습니다. V call() throws Exception 메서드를 통해, 작업 실행 후 결과를 반환하고, 필요한 경우 예외를 던질 수 있습니다. 이러한 특징 덕분에, Callable은 작업의 실행 결과를 쉽게 처리하고, 실행 중 발생한 예외를 관리할 수 있습니다.
Callable 작업은 Executor Framework를 통해 실행되며, 작업 제출 시 반환되는 Future 객체를 사용하여 비동기적으로 결과를 조회하고, 실행 중 발생한 예외를 처리할 수 있습니다.
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableExample implements Callable<Integer> {
@Override
public Integer call() throws Exception {
// 실행하고자 하는 작업, 여기서는 간단한 계산
return 123 + 456;
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Callable<Integer> callableTask = new CallableExample();
Future<Integer> future = executorService.submit(callableTask);
// 작업의 실행이 완료되면 결과를 출력
System.out.println("Callable result: " + future.get());
executorService.shutdown();
}
}
주요 차이점
- 반환 값: Runnable은 작업 실행 후 결과를 반환할 수 없습니다. 반면, Callable은 작업의 결과를 반환할 수 있습니다.
- 예외 처리: Runnable의 run() 메서드는 예외를 던지지 않습니다. Callable의 call() 메서드는 예외를 던질 수 있으며, 이는 실행 결과 조회 시 처리될 수 있습니다.
- 실행 방법: Runnable은 직접 스레드를 생성하거나 Executor Framework를 사용하여 실행할 수 있습니다. Callable은 Executor Framework를 통해서만 실행됩니다.
특성 | Runnable |
Callable |
---|---|---|
메서드 정의 | void run() |
V call() throws Exception |
반환 값 | 반환 값 없음 | 작업 실행 결과 반환 가능 |
예외 처리 | 예외를 던질 수 없음 | 예외를 던질 수 있음 (메서드 시그니처에 정의된 대로) |
사용 방법 | 직접 Thread 생성자에 전달하거나 Executor Framework를 사용 |
주로 Executor Framework를 사용하여 실행 |
적합한 사용 시나리오 | 간단한 비동기 작업 실행 시 | 결과 반환이 필요하거나 예외 처리가 중요한 작업 실행 시 |
결론
Runnable과 Callable 인터페이스는 Java의 멀티스레딩과 병렬 처리를 위한 중요한 구성 요소입니다. 각각의 특징을 이해하고 적절한 상황에서 사용함으로써, 효율적인 멀티스레드 애플리케이션을 구현할 수 있습니다. 작업의 실행 결과를 반환하거나 예외 처리가 필요한 경우 Callable을, 그 외의 경우에는 Runnable을 사용하는 것이 좋습니다.
이제 당신은 두 인터페이스의 차이점을 명확히 이해하고, 자바 멀티스레딩을 더 효과적으로 활용할 준비가 되었습니다.
'Java' 카테고리의 다른 글
일반 재귀 대 테일리 커전: 깊은 이해와 올바른 선택 (0) | 2024.04.01 |
---|---|
@Schedule 통해서 스케줄러 돌 때 데이터가 많아질 때 상황의 생각 (0) | 2024.03.27 |
Java 8 스트림(Stream) 이해하기: 데이터 처리의 혁신 (0) | 2024.01.29 |
Java에서 hashCode()와 equals()를 함께 오버라이드하는 이유 (1) | 2024.01.22 |
synchronize 라는 키워드를 함수에 사용하면 어떻게 동작해야 하나요? (1) | 2023.12.27 |