Skip to content

[사전과제] 동시성 제어#17

Open
zhdiddl wants to merge 3 commits intohanghae-skillup:mainfrom
zhdiddl:main
Open

[사전과제] 동시성 제어#17
zhdiddl wants to merge 3 commits intohanghae-skillup:mainfrom
zhdiddl:main

Conversation

@zhdiddl
Copy link

@zhdiddl zhdiddl commented Jan 5, 2025

제목(title)

ConcurrentHashMap과 ReentrantLock을 사용해 동시성 관리

작업 내용

  1. ConcurrentHashMap
  • 공유 자원인 productDatabase를 ConcurrentHashMap으로 구성
    private final ConcurrentHashMap<String, Integer> productDatabase = new ConcurrentHashMap<>();
  • compute() 메서드를 사용해 하나의 스레드만 재고 수정하도록 제한해서 원자성 보완
    public void order(String productName, int amount) {
        productDatabase.compute(productName, (key, currentStock) -> {

....
                return currentStock - amount; // 기존 재고에서 주문 수량 차감
            }
            System.out.println("[ERROR] 재고 부족: " + productName);
            return currentStock; // 차감할 수 없으면 기존 재고 유지
        });
    }
  • 동시성 이슈 해결을 테스트 코드 결과로 확인
Thread 341 주문 정보:
   apple: 1 건 ([8])
Thread 360 주문 정보:
   apple: 1 건 ([8])
Thread 384 주문 정보:
   apple: 1 건 ([8])
Thread 383 주문 정보:
   apple: 1 건 ([8])
Thread 382 주문 정보:
   apple: 1 건 ([8])
Thread 381 주문 정보:
   apple: 1 건 ([8])
Thread 380 주문 정보:
   apple: 1 건 ([8])
Thread 379 주문 정보:
   apple: 1 건 ([8])
Thread 378 주문 정보:
   apple: 1 건 ([8])
Thread 377 주문 정보:
   apple: 1 건 ([8])
Thread 376 주문 정보:
   apple: 1 건 ([8])
Thread 375 주문 정보:
   apple: 1 건 ([8])
Expected Stock: 4, Actual Stock: 4
  1. ReentrantLock
  • 주문 코드 블록에 직접 락을 적용해서 동시성 관리
    // ReentrantLock 객체 추가
    private final ReentrantLock lock = new ReentrantLock();
  • 데드락 발생 방지를 위해 락 해제 명시
 public void order(String productName, int amount) {
        lock.lock(); // 락 획득
        try {
...// 재고 체크 및 주문 로직
            }
        } finally {
            lock.unlock(); // 락 해제 
        }
    }
  • ConcurrentHashMap과 마찬가지로 테스트 통과

이번 주차에서 고민되었던 지점이나, 어려웠던 점을 알려 주세요.

  • 키워드로 언급되었던 ThreadLocal을 활용해 동시성 이슈를 해결해보려 했으나 적절한 활용 방법을 찾지 못했습니다. 주문 내역을 ThreadLocal로 구성한 경우, productDatabase를 각 스레드가 독립적으로 복사해서 사용하는 문제가 있었습니다. 결국 ReentrantLock을 추가로 사용해야 정확한 재고 감소가 이루어지는 것으로 확인했습니다. 제가 해당 개념을 맞게 이해한 것인지 궁금합니다.

- 공유 자원인 `productDatabase`를 ConcurrentHashMap으로 구성
- compute() 메서드를 사용해 하나의 스레드만 재고 수정하도록 제한해서 원자성 보완
- 동일한 key에 대해 동시 접근 경합이 발생하면서 데이터 일관성을 유지하는 구조
- 상품명을 key로 사용해서 특정 상품만 락을 걸고 나머지는 병렬로 처리 가능
- 주문 코드 블록에 직접 락을 적용해서 동시성 관리
- 데드락이 발생하지 않도록 락 해제를 명시
- 전체 자원에 락이 걸리기 때문에 여러 상품에 대한 주문 병렬 처리 불가
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant