Runnable vs Thread

전홍영·2022년 11월 8일
0

Java

목록 보기
8/15

동시성 문제에 대해 공부하던 중 Runnable Interface와 Thread에 정리할 필요가 있었다.

쓰레드란..?

쓰레드란 프로그램 실행의 가장 작은 단위로 자바 애플리케이션을 만들어 사용하면 1개의 main 쓰레드에 의해 프로그램이 실행된다. 여러 쓰레드를 사용하기 위해서는 따로 쓰레드를 만들어 실행 시켜주어야 한다.

쓰레드 구현 방법

쓰레드를 구현하는 방법은 Thread 클래스를 상속받아 구현하거나 Runnable 인터페이스를 implements 하여 구현하는 2가지 방법이 있다.

Thread Class

Thread 클래스를 이용한다면 Thread 클래스를 상속받아 내부에서 run 메소드를 구현한다. 그후 Thread의 start 메소드를 호출하면 run 메소드가 실행된다.

static class ThreadExample extends Thread {
	@Override
    public void run() {
    	System.out.println("run Thread);
    }
}

@Test
void ThreadTest() {
	Thread thread = new ThreadExample();
    thread.start();
}

Thread 클래스에서 제공하는 메소드

  • sleep : 현재 쓰레드를 멈추는 메소드
  • interupt : 다른 쓰레드를 꺠워서 interruptedException을 발생시킨다.
  • join : 다른 쓰레드의 작업이 끝날 때까지 기다리게 한다.

start 호출시 주의 점

run 메소드를 직접 호출하는 것이 아닌 start를 호출하여 run메소드를 호출하는 이유는 직접 run을 호출하는 것은 메인 쓰레드에서 객체의 메소들르 호출하는 것에 불과하기 때문에 별도의 쓰레드로 실행시키려면 JVM의 도움이 필요하다. start 메소드를 살펴보자

public synchronized void start() {
    if (threadStatus != 0)
        throw new IllegalThreadStateException();

    group.add(this);

    boolean started = false;
    try {
        start0();
        started = true;
    } finally {
        try {
            if (!started) {
                group.threadStartFailed(this);
            }
        } catch (Throwable ignore) {
        
        }
    }
}

start 메소드는 다음과 같은 과정으로 진행된다.

  1. 쓰레드가 실행 가능한지 검사한다.
    • 쓰레드는 New, Runnable, waiting, Time Wating , Terminated 5가지 상태가 있다. start 가장 처음에는 해당 쓰레드가 실행 가능한 상태인지 확인한다. New(0)이 아니라면 예외를 발생시킨다.
  2. 쓰레드를 쓰레드 그룹에 추가한다.
    • 쓰레드 그룹에 해당 쓰레드를 추가하면 쓰레드 그룹에 실행 준비된 쓰레드가 있음을 알려주고, 관련 작업들이 내부적으로 진행된다.
  3. 쓰레드를 JVM이 실행시킨다.
    • start 메소드에 보면 start0 메소드가 있는데 이 메소드가 바로 JVM이 run을 호출하는 것이다. 그리고 쓰레드의 상태도 Runnable로 바뀌게 된다.

Runnable 인터페이스

Java는 다중 상속을 지원하지 않는다.

따라서 Thread는 클래스를 상속받게 되면 다른 클래스를 상속받을 수 없다. 그래서 Runnable 인터페이스를 구현하여 쓰는 경우가 많다.

사용법

Runnable 인터페이스는 함수형 인터페이스로 람다로도 사용이 가능하다.

Runnable ex2 = new Runnable(){
	@Override 
    public void run(){
    	System.out.println("Runnable Example");
    }
};
Runnable ex = () -> System.out.println("Runnable example"); //람다 사용
Thread thread = new Thread(ex);
thread.start();

Runnable vs Thread

Runnable과 Thread 모두 쓰레드 구현이 가능하지만 여러 측면으로 Runnable을 쓰는 것이 좋다. Runnable은 람다도 사용가능하고 상속할 필요도 없으며 자우너 사용량도 Thread보다 적다. 그러나 Thread 관련 기능의 확장이 필요한 경우에는 Thread 클래스를 상속받아 구현해야 하는 경우도 있다. 그러나 대부분 Runnable 인터페이스를 사용하면 해결이 가능하다.

profile
Don't watch the clock; do what it does. Keep going.

0개의 댓글