Java Thread

다중 스레드 프로그래밍

Java에서 다중 스레드 프로그래밍은 여러 스레드가 동시에 실행되는 환경에서 작업을 처리하는 기술을 말합니다. 이를 통해 프로그램의 성능을 향상시키고 병렬 처리를 가능하게 합니다. 다음은 다중 스레드 프로그래밍의 주요 개념과 관련된 내용입니다.

스레드 개념과 생명주기

스레드는 프로세스 내에서 독립적으로 실행될 수 있는 가장 작은 단위입니다. Java에서는 Thread 클래스나 Runnable 인터페이스를 구현하여 스레드를 생성하고 실행할 수 있습니다. 스레드의 생명주기는 다음과 같은 상태로 나뉩니다:

  1. NEW: 스레드가 생성되었지만 아직 시작되지 않은 상태.
  2. RUNNABLE: 스레드가 JVM에 의해 실행되는 상태.
  3. BLOCKED: 스레드가 동기화된 블록에 의해 일시적으로 중단된 상태.
  4. WAITING: 스레드가 다른 스레드가 통지할 때까지 기다리는 상태.
  5. TIMED_WAITING: 일정 시간 동안 기다리는 상태.
  6. TERMINATED: 스레드 실행이 완료된 상태.

스레드 예제:

public class ThreadExample extends Thread {
    public void run() {
        System.out.println("스레드가 실행 중입니다.");
    }

    public static void main(String[] args) {
        ThreadExample thread = new ThreadExample();
        thread.start(); // 스레드 실행
    }
}

동기화와 락

여러 스레드가 공유 자원에 접근할 때 데이터의 일관성과 정확성을 보장하기 위해 동기화가 필요합니다. Java에서는 synchronized 키워드나 Lock 인터페이스를 사용하여 동기화를 구현할 수 있습니다.

동기화 예제:

public class SynchronizationExample {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizationExample syncExample = new SynchronizationExample();

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                syncExample.increment();
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                syncExample.increment();
            }
        });

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

        thread1.join();
        thread2.join();

        System.out.println("최종 카운트 값: " + syncExample.count); // 예상 결과: 2000
    }
}

위의 예제에서는 synchronized 메서드를 사용하여 increment() 메서드를 동기화하고, 두 개의 스레드가 동시에 해당 메서드를 호출할 때 데이터 일관성을 유지하도록 합니다.

스레드 풀과 Executor 프레임워크

스레드 풀은 다수의 스레드를 관리하고 재사용할 수 있는 기능을 제공하여 스레드 생성 및 소멸에 따른 오버헤드를 줄입니다. Java에서는 ExecutorService 인터페이스와 Executors 유틸리티 클래스를 사용하여 스레드 풀을 만들고 관리할 수 있습니다.

Executor 프레임워크 예제:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(2); // 최대 2개의 스레드를 갖는 스레드 풀 생성

        executor.submit(() -> {
            System.out.println("Task 1: 스레드 " + Thread.currentThread().getName() + "에서 실행");
        });

        executor.submit(() -> {
            System.out.println("Task 2: 스레드 " + Thread.currentThread().getName() + "에서 실행");
        });

        executor.shutdown(); // 작업 완료 후 스레드 풀 종료
    }
}

위의 예제에서는 Executors.newFixedThreadPool() 메서드로 고정 크기의 스레드 풀을 생성하고, submit() 메서드를 사용하여 각각의 작업을 스레드 풀에 제출합니다. shutdown() 메서드로 스레드 풀을 종료합니다.

다중 스레드 프로그래밍은 Java의 중요한 기능 중 하나로, 스레드 개념, 생명주기, 동기화, 스레드 풀과 Executor 프레임워크를 잘 이해하고 활용할 수 있어야 합니다. 이를 통해 프로그램의 성능을 향상시키고 병렬 처리를 구현할 수 있습니다.

Leave a Reply

Your email address will not be published. Required fields are marked *