콘텐츠로 이동

🚀 자바 스레드와 분산처리 완벽 가이드

클라우드 엔지니어를 꿈꾸는 자바 초보자를 위한 친절한 안내서


📚 목차

  1. 스레드란 무엇인가?
  2. 왜 스레드가 중요한가?
  3. 스레드 실생활 예제
  4. 자바에서 스레드 사용하기
  5. 분산처리와 Redis
  6. 클라우드 환경에서의 활용

🧵 스레드란 무엇인가?

스레드(Thread)는 프로그램 안에서 동시에 여러 가지 일을 할 수 있게 해주는 기술입니다.

🏠 실생활 비유로 이해하기

집에서 요리하는 상황을 생각해보세요:

graph TD
    A[엄마 혼자 요리하기] --> B[밥 짓기 30분]
    B --> C[반찬 만들기 20분]
    C --> D[국 끓이기 15분]
    D --> E[총 65분 소요]

    F[가족이 함께 요리하기] --> G[엄마: 밥 짓기 30분]
    F --> H[아빠: 반찬 만들기 20분]
    F --> I[언니: 국 끓이기 15분]
    G --> J[총 30분 소요!]
    H --> J
    I --> J
  • 싱글 스레드: 엄마 혼자 모든 요리를 순서대로 (65분)
  • 멀티 스레드: 가족이 함께 동시에 요리하기 (30분)

🎯 왜 스레드가 중요한가?

1️⃣ 성능 향상

  • 여러 작업을 동시에 처리하여 시간 단축
  • CPU를 효율적으로 사용

2️⃣ 사용자 경험 개선

  • 앱이 멈추지 않고 부드럽게 동작
  • 파일 다운로드 중에도 다른 기능 사용 가능

3️⃣ 서버 처리 능력 증대

  • 많은 사용자의 요청을 동시에 처리
  • 웹 서비스의 응답 속도 향상

🌟 스레드 실생활 예제

📱 카카오톡 메신저 예제

graph LR
    A[카카오톡 앱] --> B[메시지 받기 스레드]
    A --> C[메시지 보내기 스레드]
    A --> D[화면 업데이트 스레드]
    A --> E[알림 처리 스레드]

    B --> F[친구 메시지 실시간 수신]
    C --> G[내 메시지 서버로 전송]
    D --> H[채팅창 스크롤, 애니메이션]
    E --> I[푸시 알림, 소리]

만약 스레드가 없다면? - 메시지를 보내는 동안 새 메시지 받기 불가능 - 화면이 멈춰서 스크롤도 안 됨 - 매우 불편한 사용자 경험!


💻 자바에서 스레드 사용하기

기본 스레드 생성 방법

// 방법 1: Thread 클래스 상속
class MyThread extends Thread {
    public void run() {
        System.out.println("새로운 스레드에서 실행 중!");
    }
}

// 방법 2: Runnable 인터페이스 구현 (추천)
class MyTask implements Runnable {
    public void run() {
        System.out.println("작업 실행 중!");
    }
}

// 사용법
public class ThreadExample {
    public static void main(String[] args) {
        // 방법 1 사용
        MyThread thread1 = new MyThread();
        thread1.start();

        // 방법 2 사용
        Thread thread2 = new Thread(new MyTask());
        thread2.start();
    }
}

🍕 피자 주문 처리 시스템 예제

class PizzaOrderProcessor implements Runnable {
    private String customerName;

    public PizzaOrderProcessor(String name) {
        this.customerName = name;
    }

    public void run() {
        System.out.println(customerName + "님의 주문 처리 시작");

        try {
            Thread.sleep(3000); // 피자 만드는 시간 (3초)
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(customerName + "님의 피자 완성!");
    }
}

public class PizzaShop {
    public static void main(String[] args) {
        // 동시에 여러 주문 처리
        Thread order1 = new Thread(new PizzaOrderProcessor("김철수"));
        Thread order2 = new Thread(new PizzaOrderProcessor("이영희"));
        Thread order3 = new Thread(new PizzaOrderProcessor("박민수"));

        order1.start();
        order2.start();
        order3.start();

        // 3개 주문이 동시에 처리됨!
    }
}

🌐 분산처리와 Redis

분산처리란?

하나의 큰 일을 여러 컴퓨터가 나누어서 처리하는 것입니다.

graph TD
    A[대용량 데이터 처리 작업] --> B[서버 1]
    A --> C[서버 2]
    A --> D[서버 3]
    A --> E[서버 4]

    B --> F[결과 1]
    C --> G[결과 2]
    D --> H[결과 3]
    E --> I[결과 4]

    F --> J[최종 결과 통합]
    G --> J
    H --> J
    I --> J

🏪 편의점 체인점 비유

graph LR
    A[CU 본사] --> B[강남점]
    A --> C[홍대점]
    A --> D[신촌점]

    B --> E[재고 관리]
    C --> F[매출 관리]
    D --> G[고객 관리]

    E --> H[Redis 중앙 데이터베이스]
    F --> H
    G --> H
  • 본사 = 메인 서버
  • 각 지점 = 분산된 서버들
  • Redis = 모든 지점이 공유하는 중앙 창고

📊 Redis를 활용한 분산처리

Redis란?

  • Remote Dictionary Server
  • 메모리에 데이터를 저장하는 고속 데이터베이스
  • 여러 서버가 공유할 수 있는 중앙 저장소 역할

실무에서의 활용 예

sequenceDiagram
    participant U as 사용자
    participant S1 as 서버1
    participant S2 as 서버2
    participant R as Redis

    U->>S1: 로그인 요청
    S1->>R: 세션 정보 저장
    R-->>S1: 저장 완료
    S1-->>U: 로그인 성공

    U->>S2: 다른 페이지 요청
    S2->>R: 세션 정보 조회
    R-->>S2: 세션 정보 전달
    S2-->>U: 인증된 사용자로 응답

🛒 쇼핑몰 장바구니 시스템 예제

// Redis를 활용한 장바구니 관리
public class ShoppingCartService {
    private RedisTemplate<String, Object> redisTemplate;

    // 장바구니에 상품 추가
    public void addToCart(String userId, String productId, int quantity) {
        String key = "cart:" + userId;
        redisTemplate.opsForHash().put(key, productId, quantity);

        // 24시간 후 자동 삭제
        redisTemplate.expire(key, 24, TimeUnit.HOURS);
    }

    // 장바구니 조회
    public Map<String, Integer> getCart(String userId) {
        String key = "cart:" + userId;
        return redisTemplate.opsForHash().entries(key);
    }
}

장점: - 🚀 빠른 속도: 메모리에서 데이터 처리 - 🔄 서버 간 공유: 어느 서버에 접속해도 같은 장바구니 - ⏰ 자동 만료: 불필요한 데이터 자동 정리


☁️ 클라우드 환경에서의 활용

마이크로서비스 아키텍처

graph TB
    subgraph "사용자"
        U[모바일 앱/웹]
    end

    subgraph "로드 밸런서"
        LB[Load Balancer]
    end

    subgraph "마이크로서비스들"
        US[사용자 서비스]
        PS[상품 서비스]
        OS[주문 서비스]
        CS[결제 서비스]
    end

    subgraph "공유 자원"
        R[Redis Cluster]
        DB[(Database)]
    end

    U --> LB
    LB --> US
    LB --> PS
    LB --> OS
    LB --> CS

    US --> R
    PS --> R
    OS --> R
    CS --> R

    US --> DB
    PS --> DB
    OS --> DB
    CS --> DB

실무 활용 시나리오

1️⃣ 세션 클러스터링

// 여러 서버가 사용자 로그인 상태 공유
@Service
public class SessionService {
    public void createSession(String userId, String sessionId) {
        // Redis에 세션 정보 저장
        redisTemplate.opsForValue().set(
            "session:" + sessionId, 
            userId, 
            30, TimeUnit.MINUTES
        );
    }
}

2️⃣ 캐싱으로 성능 향상

@Service
public class ProductService {

    @Cacheable(value = "products", key = "#productId")
    public Product getProduct(Long productId) {
        // 첫 번째 요청시에만 DB 조회
        // 이후 요청은 Redis에서 빠르게 응답
        return productRepository.findById(productId);
    }
}

3️⃣ 분산 락으로 동시성 제어

@Service
public class InventoryService {

    public boolean purchaseProduct(Long productId, int quantity) {
        // 재고 차감시 동시성 문제 해결
        String lockKey = "lock:product:" + productId;

        try (RLock lock = redisson.getLock(lockKey)) {
            if (lock.tryLock(5, TimeUnit.SECONDS)) {
                // 안전하게 재고 차감 처리
                return processInventory(productId, quantity);
            }
            return false;
        }
    }
}

🎯 클라우드 엔지니어로서 알아야 할 핵심 포인트

1️⃣ 확장성 (Scalability)

graph LR
    A[사용자 증가] --> B[서버 부하 증가]
    B --> C[새로운 서버 추가]
    C --> D[Redis로 상태 공유]
    D --> E[부하 분산 완료]

2️⃣ 고가용성 (High Availability)

graph TD
    A[마스터 Redis] --> B[슬레이브 Redis 1]
    A --> C[슬레이브 Redis 2]

    D[마스터 장애 발생] --> E[자동 페일오버]
    E --> F[슬레이브가 마스터로 승격]
    F --> G[서비스 중단 없음]

3️⃣ 모니터링과 로깅

@Component
public class PerformanceMonitor {

    @EventListener
    public void logSlowQueries(SlowQueryEvent event) {
        // 느린 쿼리 감지 및 알림
        if (event.getExecutionTime() > 1000) {
            log.warn("Slow query detected: {} ms", 
                    event.getExecutionTime());
        }
    }
}

📝 정리 및 다음 단계

✅ 오늘 배운 것들

  • 스레드: 동시에 여러 작업을 처리하는 기술
  • 분산처리: 여러 서버가 협력하여 큰 작업 처리
  • Redis: 고속 메모리 데이터베이스로 서버 간 데이터 공유
  • 클라우드 활용: 확장 가능하고 안정적인 시스템 구축

🚀 다음 학습 추천

  1. Spring Boot로 REST API 만들기
  2. Docker로 애플리케이션 컨테이너화
  3. Kubernetes로 컨테이너 오케스트레이션
  4. AWS/GCP/Azure 클라우드 서비스 활용
  5. 모니터링 도구 (Prometheus, Grafana) 학습

💡 실습 프로젝트 아이디어

  • 간단한 채팅 애플리케이션 (WebSocket + Redis)
  • 쇼핑몰 장바구니 시스템 (Spring Boot + Redis)
  • 파일 업로드/다운로드 시스템 (멀티스레드 활용)

🎉 마무리

클라우드 엔지니어의 길은 처음엔 복잡해 보이지만, 하나씩 차근차근 배워나가면 충분히 달성할 수 있습니다!

기억하세요: - 🧵 스레드로 동시 처리 능력 향상 - 🌐 분산처리로 확장 가능한 시스템 구축
- 📊 Redis로 고성능 데이터 공유 - ☁️ 클라우드로 안정적인 인프라 운영

화이팅! 💪