IT/Java

Runnable과 Thread

김 정 환 2023. 1. 11. 23:26
반응형
반응형

 

자바에서 스레드를 구현할 수 있는 방법은 두 가지가 있습니다.

 

Runnable

Runnable은 인터페이스 입니다.

인터페이스를 이용해서 구현하면 재사용성이 높고 코드의 일관성을 유지할 수 있습니다.

또한, 다른 클래스를 상속 받아서 사용할 수 있습니다.

 

Runnable 인터페이스는 아래와 같습니다. 추상 메서드 run()를 가지고 있어서 반드시 오버라이딩하여 구현해 주어야 합니다.

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

 

사용 예시는 아래와 같습니다.

printNum을 재사용하여 스레드를 만들 수 있습니다.

    @Test
    public void runnable() {

        Runnable printNum = new RunnableClass(10);

        Thread thread1 = new Thread(printNum);
        Thread thread2 = new Thread(printNum);

        thread1.start();
        thread2.start();

    }

    static class RunnableClass implements Runnable {

        int num;

        public RunnableClass(int num) {
            this.num = num;
        }

        @Override
        public void run() {
            for(int i=0; i<=num; ++i){
                System.out.println(i);
            }
        }
    }

 

 

 

Thread

Thread는 클래스 입니다.

사용할 때에는 상속(extends)하여 사용해야 합니다. 그래서 다른 클래스를 상속 받을 수 없습니다.

 

Thread 클래스는 아래와 같습니다. Runnable 인터페이스를 상속받고 있습니다.

public class Thread implements Runnable {
    /* Make sure registerNatives is the first thing <clinit> does. */
    private static native void registerNatives();
    static {
        registerNatives();
    }
    
    /// 중략 ///
    
        /**
     * If this thread was constructed using a separate
     * {@code Runnable} run object, then that
     * {@code Runnable} object's {@code run} method is called;
     * otherwise, this method does nothing and returns.
     * <p>
     * Subclasses of {@code Thread} should override this method.
     *
     * @see     #start()
     * @see     #stop()
     * @see     #Thread(ThreadGroup, Runnable, String)
     */
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
    
 }

 

사용 예시는 아래와 같습니다. 

thread1과 thread2 인스턴스를 각각 만들어서 사용하고 있습니다.

    @Test
    public void thread() {

        ThreadClass thread1 = new ThreadClass(10);
        ThreadClass thread2 = new ThreadClass(10);

        thread1.start();
        thread2.start();

    }

    static class ThreadClass extends Thread {

        int n;

        public ThreadClass(int n) {
            this.n = n;
        }

        @Override
        public void run(){
            for (int i = 0; i < n; i++) {
                System.out.println(i);
            }
        }

    }

 

 

 

Runnable과 Thead 사용에 대한 생각

자바에서는 다중상속을 허용하지 않습니다.  Runnable 인터페이스를 사용하여 구현하면 다른 클래스를 상속 받을 수 있기 때문에 확장성에서 득을 볼 수 있다고 생각합니다. 

 

 

 

스레드 사용할 때 주의사항 : start()과 run() 사용

run()을 호출하는 것은 생성한 스레드 객체를 실행하는 것이 아니라, 단순히 스레드 클래스 내부의 run()을 실행시키는 것 입니다. run()를 사용하면 main()의 메인 스레드가 run() 메소드를 실행하기 때문에 새로운 스레드가 생기지 않아서 병렬 처리를 할 수 없습니다. 

 

반면, start()를 이용하면 새로운 스레드 실행에 필요한 호출 스택(call stack)을 생성하고 run()을 호출합니다. 생성된 호출 스택에 run()을 담습니다 (스택에 올라가면 메서드는 실행됩니다) 따라서 멀티 스레드로 병렬 처리를 할 수 있습니다.

 

 

 

참고

- 내용 : https://hyeo-noo.tistory.com/293

- 내용 : https://velog.io/@ksung1889/호출스택Call-stack이-뭔데

반응형

'IT > Java' 카테고리의 다른 글

자바의 비동기 API  (0) 2023.01.15
프로세스와 스레드 그리고 멀티 태스킹  (0) 2023.01.10
동시성(Concurrency) 과 병렬성(Parallel)  (0) 2023.01.10
Optional 클래스 사용  (0) 2023.01.08
Map 처리  (0) 2022.12.19