본문으로 바로가기

[Java] 자바 Thread 생성하기

category Backend/Java 2022. 1. 4. 13:13

1. Process And Thread

프로세스

  • 프로세스는 운영체제로부터 자원을 할당받는 작업의 단위
  • 프로세스는 실행될 때 운영체제로부터 필요한 주소 공간, 메모리 등 자원을 할당받습니다.

스레드

  • 스레드는 프로세스가 할당받은 자원을 이용하는 실행의 단위
  • 스레드란 한 프로세스 내에서 동작되는 여러 실행의 흐름으로 프로세스 내의 주소 공간이나 자원들을 같은 프로세스 내에 스레드끼리 공유하면서 실행합니다.

2. Thread를 왜 사용할까?

  • 답은 간단합니다. 시스템 자원을 효율적으로 관리하기 위해서입니다.
  • 멀티 프로세스 활용해 한번에 여러 프로그램을 돌릴 수 있지만 상황에 따라 멀티 스레드를 활용해 실행할 경우 프로세스를 생성하여 자원을 할당하는 시스템 콜이 줄어들어 자원을 효율적으로 관리할 수 있습니다.
  • 프로세스 간의 통신보다 스레드 간의 통신의 비용이 적으므로 작업들 간의 통신의 부담이 줄어들게 됩니다.
  • 그러나 스레드 간의 자원 공유는 전역 변수를 이용하므로 동기화 문제에 프로그래머가 매우 신경을 써야 합니다.

3. Thread 만들기

  • Thread 클래스와 Runnable 함수형 인터페이스를 구현해 Thread를 생성합니다.
  • 자바로 Thread 만드는 방법 2 가지 방법이 있습니다.
  • Thread의 실행 순서는 보장할 수 없습니다. (어떤 것이 먼저 실행될지 모릅니다.)

Thread Class

public class Thread implements Runnable {

    public static native void sleep(long millis) throws InterruptedException;
    
    public void interrupt() {
        if (this != Thread.currentThread()) {
            checkAccess();

            // thread may be blocked in an I/O operation
            synchronized (blockerLock) {
                Interruptible b = blocker;
                if (b != null) {
                    interrupt0();  // set interrupt status
                    b.interrupt(this);
                    return;
                }
            }
        }

    public final void join() throws InterruptedException {
        join(0);
    }
    
    // (. . .) 생략
}

Runnable FunctionalInterface

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

 

1. Thread 상속받아 만들기

// 상속 받아서 스레드 만들기
static class TestThread extends Thread {
    @Override
    public void run() {
        System.out.println("Thread Test " + Thread.currentThread().getName());
    }
}

// 스레드 생성
TestThread testThread = new TestThread();
testThread.start();

// Main 실행
System.out.println("Main Test " + Thread.currentThread().getName()); // main 스레드

2. 익명 클래스 구현 또는 람다로 사용

Runnable은 함수형 인터페이스이므로 구현 시 익명 클래스나 람다를 사용할 수 있습니다.

// 익명 클래스로 스레드 만들기
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Thread Test " + Thread.currentThread().getName());
    }
});
thread.start();

System.out.println("Main Test " + Thread.currentThread().getName()); // main 스레드
// 람다로 스레드 만들기
Thread thread = new Thread(() -> {
    System.out.println("Thread Test " + Thread.currentThread().getName());
});
thread.start();

System.out.println("Main Test " + Thread.currentThread().getName()); // main 스레드

 

실행 결과

다음과 같이 실행 순서에는 보장이 없습니다.