[Java] Runnable, Thread, 동기화

gyeol·2025년 10월 1일
0

자바

목록 보기
19/23
post-thumbnail

자바에서 멀티스레드를 사용할 때 크게 2가지 방법이 있다.

  • Thread 클래스를 상속받아 run() 메서드 오브라이드
  • Runnable 인터페이스를 구현해 Thread 생성자에게 전달

하지만 자바는 다중 상속을 지원하지 않기에 다른 클래스를 상속한 경우 Runnable 인터페이스를 구현해야 스레드로 동작시킬 수 있다.

Runnable vs Thread

  • Thread 상속 : 단일 상속
  • Runnable 구현 : 다중 상속 가능
class Bus extends Car implements Runnable {
    @Override
    public void run() {
        System.out.println("버스가 달리고 있습니다.");
    }
}

동기화

멀티스레드 환경에서는 Race Condition이 발생할 수 있습니다. 이를 해결하기 위해 synchronized 키워드 또는 Lock을 사용해 임계 구역을 보호해야 한다.

Race Condition?
두 개 이상의 스레드가 동시에 같은 객체를 수정하려고 하면 결과가 꼬임

synchronized (order) {
    if (!order.isProcessed()) {
        order.setProcessed(true);
        System.out.println("Order " + order.id + " processed!");
    }
}

예시

  • Order 객체는 id, status (NEW, PROCESSING, COMPLETED, CANCELLED)를 가진다.
  • OrderProcessor 인터페이스를 정의하고, process(Order order) 메소드를 갖는다.
  • CreditCardOrderProcessor, PayPalOrderProcessor 같은 구현체가 존재한다.
  • 같은 주문을 여러 번 처리 요청할 수 있지만, 최초 1회만 처리되고 이후는 무시해야 한다.
  • 멀티스레드 환경에서도 동작해야 한다.

입력

Order order = new Order(1001, "NEW");
OrderProcessor processor = new CreditCardOrderProcessor();
Thread t1 = new Thread(() -> processor.process(order));
Thread t2 = new Thread(() -> processor.process(order));
t1.start();
t2.start();

출력

Order 1001 is processed by CreditCard.

내 코드

interface OrderProcessor {
    public void process(Order order);
}

public class test {
    public static void main(String[] args) {
        Order order = new Order(1001, "NEW");
        OrderProcessor processor = new CreditCardOrderProcessor();
        Thread t1 = new Thread(() -> processor.process(order));
        Thread t2 = new Thread(() -> processor.process(order));
        t1.start();
        t2.start();
    }
}
class CreditCardOrderProcessor implements OrderProcessor{

    @Override
    public void process(Order order) {
        synchronized(order){
            if(!order.isProcessed()){
                System.out.println("Order" + order.id + " is processed by CreditCard");
                order.setProcessed(true);
            }
        }
        
    }
    
}

class PayPalOrderProcessor implements OrderProcessor{

    @Override
    public void process(Order order) {
        synchronized(order){
            if(!order.isProcessed()){
                System.out.println("Order" + order.id + " is processed by PayPal");
                order.setProcessed(true);
            }
        }
        
    }
    
}

class Order{
    int id;
    String status;
    private boolean processed = false;

    public Order(int id, String status){
        this.id = id;
        this.status = status;
    }

    public boolean isProcessed(){
        return processed;
    }

    public void setProcessed(boolean processed) {
        this.processed = processed;
    }
}
profile
공부 기록 공간 '◡'

0개의 댓글