Runnable, Callable

namkun·2023년 9월 4일
0

T-I-L

목록 보기
20/20

Runnable과 Callable 모두 멀티스레드에서 작업을 수행할 수 있게 설계되어있습니다.

Runnable 작업들은 Thread 클래스 또는 ExecutorService 에서 실행할 수 있으나, Callable은 오직 ExecutorService 에서 만 실행할 수 있습니다.

Runnable

Runnable은 멀티스레드 작업을 표현하기 위해서 자바에서 제공하는 인터페이스 입니다.

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

오직 run() 메서드만 갖고 있고, 어떠한 파라미터도 없으며 어떠한 값도 반환받지 않습니다.

그렇기에 스레드의 결과값이 필요하지 않을때 사용합니다.

예를 들면 아래처럼요.

thread class

@Slf4j
public class EventLoggingTask implements Runnable {
	@Override
    public void run(){
    	log.info("MSG");
    }
}

run method

public void executeTask(){
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.execute(new Thread(EventLoggingTask::new));
        executorService.shutdown();
}

위 경우는 단순하게 스레드 내부의 run이 실행될 뿐입니다.

Callable

Callable 인터페이스는 generic 값인 V를 반환하는 call() 메서드만 포함하는 인터페이스입니다.

@FunctionalInterface
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

위의 Runnable과 다른점이라면 결과값을 계산할 수 없는 경우 Exception을 던진다는 점입니다.

아래의 예시를 통해 이해해봅시다.

thread class

public class FactorialTask implements Callable<Integer> {
    int number;

    public FactorialTask(int number) {
        this.number = number;
    }

    @Override
    public Integer call() throws Exception {
        int fact = 1;
        for(int count = number; count > 1; count--) {
            fact = fact * count;
        }
        return fact;
    }
}

위처럼 스레드 클래스에서 Integer 값을 반환할 수 있게 해두었습니다.

call Method

    public void whenTaskSubmitted_ThenFutureResultObtained() throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        FactorialTask task = new FactorialTask(5);
        Future<Integer> future = executorService.submit(task);
        Integer result = future.get();
        System.out.println(result);
    }

위처럼 사용하면, submit 함과 동시에 스레드 내부의 call 이 실행됩니다.

그리고 이를 Future class를 통해 반환 받은 뒤, get() 메서드를 이용해서 가져올 수 있게 됩니다.


Runnable과 Callable에 대해서 알아보았습니다.

상황에 맞게 잘 사용하면 될 것 같습니다.

profile
개발하는 중국학과 사람

1개의 댓글

comment-user-thumbnail
2025년 5월 29일

Really unquie place, Thank you so much meant for posting The experience. Fantasticly penned report, anxieties most of folks given similar volume of material as you may, the online market place might be a a lot better put. Be sure to keep it up! thca flower in arizona

답글 달기