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 작업을 스레드 풀에 맡겨 효율적으로 실행
장점 성능, 스레드 재사용, 예외/종료 처리 용이
언제? 다수의 작업, 비동기 처리, 성능 최적화, 코드 간결화 필요

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형