자바

자바 멀티 스레드 개념 정리

a-bell2 2025. 6. 6. 18:31

 

💡 자바 멀티 스레드 개념 정리

✅ 프로세스 vs 스레드 개념 이해

  • 프로세스: 실행 중인 하나의 프로그램 단위로, 운영체제가 메모리를 따로 할당해 관리합니다.
  • 스레드: 프로세스 내에서 실제 작업을 수행하는 실행 흐름. 하나의 프로세스는 여러 개의 스레드를 가질 수 있습니다.

📝 예: 메모장을 두 개 실행하면 두 개의 프로세스가 생기고, 각 프로세스 내부에는 메인 스레드가 있습니다.


✅ 멀티 스레드란?

  • 하나의 프로세스 내에서 **여러 작업 흐름(스레드)**을 동시에 수행하는 구조입니다.
  • 음악을 들으며 채팅하거나, 대용량 데이터를 동시에 처리하는 기능은 모두 멀티스레드 덕분입니다.

🔹 멀티 스레드 특징

항목  설명
실행 방식 한 프로세스 내에서 여러 작업을 동시에 실행
자원 공유 동일한 메모리 공간을 공유하므로 협업이 빠르지만 충돌 위험도 존재
예외 발생 시 한 스레드의 문제로 전체 프로세스가 종료될 수 있음

✅ 메인 스레드와 작업 스레드

  • main() 메소드를 실행하는 스레드를 메인 스레드라고 부릅니다.
  • 메인 스레드에서 새로운 스레드를 생성하면, 이를 작업 스레드라고 합니다.
public class Main {
    public static void main(String[] args) {
        System.out.println("메인 스레드 시작");

        Thread thread = new Thread(() -> {
            System.out.println("작업 스레드 실행 중");
        });
        thread.start();

        System.out.println("메인 스레드 종료");
    }
}

🔸 실행 순서는 CPU 스케줄링에 따라 달라질 수 있습니다.


✅ 스레드 생성 방법

1. Runnable 인터페이스 구현

Thread thread = new Thread(() -> {
    System.out.println("작업 스레드 실행 중");
});
thread.start();
  • Runnable은 run() 메서드 하나만 가진 함수형 인터페이스입니다.
  • 람다식으로 간결하게 작성할 수 있어 실무에서 자주 사용됩니다.

2. Thread 클래스를 상속

class MyThread extends Thread {
    public void run() {
        System.out.println("작업 스레드 실행 중");
    }
}

new MyThread().start();
  • Thread를 상속받기 때문에 다른 클래스를 동시에 상속할 수 없습니다.
  • 구조는 간단하지만 유연성은 떨어집니다.

✅ 스레드 이름 관리

  • 디버깅 시 어떤 스레드가 실행 중인지 확인할 수 있도록 이름을 부여할 수 있습니다.
Thread thread = new Thread(() -> {
    System.out.println("현재 스레드: " + Thread.currentThread().getName());
});
thread.setName("작업스레드1");
thread.start();
  • Thread.currentThread()는 현재 실행 중인 스레드를 참조합니다.
  • 익명 객체나 람다식 내부에서는 변수명이 없으므로 이 메서드로 현재 스레드 정보를 확인합니다.

✅ 스레드 동기화 (synchronized)

🔸 문제 상황

멀티 스레드 환경에서 **공유 자원(객체)**를 동시에 수정할 경우, 예상치 못한 결과가 발생할 수 있습니다.

public class Counter {
    private int count = 0;

    public void increase() {
        count++;
    }
}
  • 위 코드에서는 count++ 실행 중 다른 스레드가 개입하면 정확한 값이 보장되지 않습니다.

🔸 해결: 동기화 메소드

public synchronized void increase() {
    count++;
}
  • synchronized 키워드를 붙이면 **임계 영역(Critical Section)**이 설정되어 한 번에 하나의 스레드만 접근할 수 있습니다.

✅ 동기화 메소드 특징

구분  설명
객체 단위 잠금 인스턴스 메서드에 synchronized를 쓰면, 객체를 기준으로 잠금이 걸림
클래스 단위 잠금 정적 메서드에 synchronized를 쓰면, 클래스 전체에 잠금이 걸림
일반 메서드 synchronized가 없는 메서드는 다른 스레드에서 자유롭게 실행 가능
다중 synchronized 메서드 하나라도 실행 중이면 다른 synchronized 메서드도 대기 상태

✅ 요약 표

개념  설명
메인 스레드 main() 메서드를 실행하는 기본 스레드
작업 스레드 메인 스레드가 생성하는 추가 스레드
Thread 생성 Thread 상속 또는 Runnable 구현 방식
스레드 이름 setName(), getName(), Thread.currentThread()로 설정/확인 가능
동기화 처리 synchronized 키워드로 임계 영역 보호
람다 표현식 Runnable의 run() 메서드를 람다로 간단히 구현 가능

✅ 스프링 부트에서의 작업 스레드 처리

  • 웹 요청 처리: 톰캣 내부 작업 스레드가 자동으로 배정
  • 비동기 처리(@Async 등): 스프링이 스레드풀을 자동 생성해 사용
  • 개발자가 별도로 스레드를 만들지 않아도 됨 (자동 구성 덕분)