Java/Spring
Runnable 인터페이스, ExecutorService 인터페이스
Z_Z
2025. 5. 16. 10:11
반응형
Runnable 인터페이스란?
작업(Task)을 정의하기 위한 함수형 인터페이스이다.
주로 스레드에서 실행할 작업을 정의할 때 사용된다.
@FunctionalInterface
public interface Runnable {
void run();
}
- 추상 메서드인 void run() 메서드만 존재한다.
- @FuntionalInterface 가 붙어있는 함수형 인터페이스라서 람다식으로 표현 가능하다.
- 결과값이 없고 예외도 throws 하지 않는 단순한 실행 작업을 나타낸다.
✅ 언제 사용하나요?
- Thread 생성 시 실행할 작업 정의
- ExecutorService 같은 스레드 풀에 작업 제출할때 사용
✅ Thread와 함께 사용하는 예
일반 클래스
package com.obo.controller;
public class TestRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable 인터페이스 구현!");
}
}
// 구현한 클래스 new 키워드로 호출
Thread t2 = new Thread(new TestRunnable());
t2.start();
람다식 사용
Runnable r = () -> System.out.println("aaaaaaaaaaaaaaaaa");
Thread t = new Thread(r);
t.start();
✅ 요약
- Runnable 은 run() 추상 메서드 하나만 가진 함수형 인터페이스이다.
- 스레드에서 실행할 작업을 정의할 때 사용한다.
(Thread 클래스도 Runnable 인터페이스를 구현했다.) - Java 8+ 이상부터는 람다식으로 간결하게 작성 가능하다.
- Thread, ExecutorService 와 함께 자주 사용된다.
ExecutorService 인터페이스란?
멀티스레드 작업을 효율적이고 유연하게 처리하기 위해 사용된다.
Java 에서 Thread 를 직접 생성하는 대신, 스레드 풀을 관리해주는 고수준 API 다.
📌 핵심 목적
- 스레드를 재사용해서 비용 절감
- 작업 제출과 실행을 분리
- 비동기 작업 관리(Future 로 결과 받기 등)
🧱 주요 구현체
구현체 | 설명 |
Executors.newFixedThreadPool(n) | 고정된 개수의 스레드를 가지는 풀 |
Executors.newCachedThreadPool() | 필요할 때 스레드를 생성, 유휴 시 제거 |
Executors.newSingleThreadExecutor() | 하나의 스레드로 순차 실행 |
Executors.newScheduledThreadPool(n) | 예약된 작업 또는 주기적인 작업 실행용 |
🎯 자주 사용하는 메서드
메서드 | 설명 |
submit(Callable<T>) | 작업을 제출하고 Future<T> 반환 (결과 받을 수 있음) |
execute(Runnable) | 작업을 제출하고 결과는 받지 않음 |
invokeAll(Collection<Callable<T>>) | 여러 작업을 제출하고, 모두 끝날 때까지 기다림 |
shutdown() | 더 이상 작업 받지 않고 종료 준비 |
shutdownNow() | 즉시 종료 시도 (진행 중인 작업 중단) |
awaitTermination(timeout, unit) | 지정 시간 내 종료 대기 |
✅ Runnable + ExecutorService 예제
✅ 예제 1 : 결과를 반환받는 작업 (Callable + Future)
import java.util.concurrent.*;
public class ExecutorExample {
public static void main(String[] args) {
try {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<String> c = () -> {
System.out.println("Callable 테스트!");
Thread.sleep(4000);
return "완료";
};
Future<String> f = executor.submit(c);
String result = f.get();
System.out.println("result : "+result);
executor.shutdown();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
Future 클래스
Future 클래스는 Java 의 동시성 프로그래밍을 위한 인터페이스로, 비동기 작업의 결과를 나타낸다.
ExecutorService 의 submit() 메서드를 통해 비동기 작업을 실행하면 작업의 결과를 추적하고 관리하기 위해
Future 객체가 반환된다.
즉, 작업의 결과를 추적 및 관리하기 위한 클래스이다.
주요 메서드
메서드 | 설명 |
V get() | 작업이 완료될 때까지 기다렸다가 결과를 반환한다. 작업이 아직 완료되지 않았다면 호출이 블로킹된다. |
get(long timeout, TimeUnit unit) | 지정된 시간 동안만 기다렸다가 결과를 반환한다. |
isDone() | 작업이 완료되었는지 확인한다. |
isCancelled() | 작업이 취소되었는지 확인한다. |
cancel(boolean mayInterruptIfRunning) | 실행중인 작업을 취소한다. |
✅ 예제 2 : 간단한 작업 여러개 처리
import java.util.concurrent.*;
public class ExecutorExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Runnable task = () -> {
String threadName = Thread.currentThread().getName();
System.out.println("Running task on : "+threadName);
};
for (int i = 0; i < 5; i++) {
executor.execute(task);
}
executor.shutdown();
}
}
✅ 요약
개념 | 설명 |
Runnable | 실행만 하는 작업 정의 (void run()), 결과 없음 |
ExecutorService | 작업을 스레드 풀에 맡겨 효율적으로 실행 |
장점 | 성능, 스레드 재사용, 예외/종료 처리 용이 |
언제? | 다수의 작업, 비동기 처리, 성능 최적화, 코드 간결화 필요 시 |
반응형