Skip to content

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

Open
kdmstj wants to merge 5 commits intohanghae-skillup:mainfrom
kdmstj:main
Open

[사전 과제] 동시성 제어#7
kdmstj wants to merge 5 commits intohanghae-skillup:mainfrom
kdmstj:main

Conversation

@kdmstj
Copy link

@kdmstj kdmstj commented Jan 4, 2025

작업 내용

  • OrderService1 에 동시 주문 요청 메소드 synchronized 키워드를 통해 처리 기능 추가

    • 인스턴스 단위의 synchronized 메소드 설정
      public synchronized void orderUsingSynchronized(String productName, int amount) 
      
    • 블록 단위의 synchronized 메소드 설정
      public void orderUsingSynchronized2(String productName, int amount) {
          synchronized (this) {}
      }
      
  • OrderService2 에 공유 자원인 product 의 stock 을 AtomicInteger 로 관리

    • AtomicInteger.compareAndSet 메소드 내 구현된 CAS 알고리즘에 의해 값 변경
      private final Map<String, AtomicInteger> productDatabase = new HashMap<>();
      
      while(true) {
          boolean success = currentStock.compareAndSet(current, current - amount);
          if (success) {
              break;
          }
      }
      
  • OrderService3 에 공유 자원인 productDatabase 를 ConcurrentHashMap 으로 관리

    • ConcurrentHashMap.compute 메소드 내 구현된 CAS 알고리즘에 의해 값 변경
      private final Map<String, Integer> productDatabase = new ConcurrentHashMap<>();
      
      productDatabase.compute(productName, (key, currentStock) -> {
          if (currentStock == null || currentStock < amount) {
              return currentStock;
          }
          return currentStock - amount;
      });
      
      

발생했던 문제와 해결 과정을 남겨 주세요.

  • 문제 1 :
    • 다수의 사용자가 동시에 product 에 stock 를 업데이트할 때 재고 수량이 음수로 내려가는 데이터 불일치 문제 발생
  • 해결 방법 1:
    • Java 의 synchronized 키워드를 사용하여 method 나 block 단위로 모니터 락을 설정했습니다. 특정 스레드가 락을 얻어 읽고 업데이트하는 동안 다른 스레드가 접근하지 못하도록 하여 데이터 정합성을 보장하기 위함입니다.
    • 하지만 해당 방법은 blocking 방식을 사용해 성능이 저하한다는 문제가 있었습니다.
  • 해결 방법 2:
    • 공유 자원인 product 의 stock 에 대해 AtomicInteger 로 설정하였습니다. CAS 알고리즘을 통해 가시성과 원자성을 확보해 데이터의 정합성을 보장하기 위함입니다.
    • AtomicInteger 는 내부적으로 CAS 알고리즘을 사용하여 expectedValue (현재 스레드가 알고 있는 stock) 과 value (메모리에 있는 stock) 이 동일하다면 업데이트 하고, 같지 않다면 바쁜 대기 상태에 두어 다시 업데이트를 시도합니다.
  • 해결 방법 3:
    • 공유 자원인 productDatabase 에 대해 ConcurrentHashMap 에 저장하였습니다.
    • 마찬가지로 ConcurrentHashMap 은 내부적으로 CAS 알고리즘을 사용하여 가시성과 원자성을 확보하여 데이터 정합성을 보장합니다.

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

  • CAS 알고리즘을 이해하기 어려웠습니다.
    • 예를 들면, "원자성을 보장한다고 하지만 SWAP 하는 동안 다른 스레드가 변경하면 어떡하지?" 라는 해당 동작하는 동안 다른 스레드가 접근하지 못한다는 것을 알습니다.
    • 이에 추가적으로 "원자성을 보장하기 위해서 다른 스레드가 변경하지 못하도록 하는 것은 락이 아닌가?" 라는 의문점이 생겼습니다. 하지만 CAS 메서드 자체가 하드웨어 레벨에서 이루어지는 연산이기 때문에 '락'이 아니며, 하나의 CPU 코어가 특정 메모리 주소에 대해 CAS 작업 중일 때, 다른 코어들이 해당 메모리에 접근하지 못하도록 하는 원리라는 것을 알았습니다.

리뷰 포인트

  • AtomicInteger 를 사용하는 방법이 헷갈리는데, 해당 부분이 제대로 작성되었는지 궁금합니다.

기타 질문

  • AtomicInteger 를 실제로 어떻게 사용하는지 여쭤보고 싶습니다.

kdmstj added 5 commits January 4, 2025 12:01
- 하나의 공유 자원에 대해서 여러개의 스레드가 접근했을 때, 동시성 이슈가 발생하여 데이터 정합성 문제가 발생하도록 하였습니다.
- 동시성 문제를 해결하기 위해 synchronized 키워드를 적용했습니다.
- 인스턴스 단위 와 블록 단위 동기화를 통해 상호 배제를 구현하여 데이터 정합성을 보장하였습니다.
- 공유 자원인 productDatabase 의 재고 관리를 위해 AtomicInteger 를 적용하였습니다.
- compareAndSet 메서드를 활용해 CAS 알고리즘으로 가시성과 원자성을 통해 데이터의 정합성을 보장하였습니다.
- 공유 자원인 productDatabase 의 재고 관리를 위해 ConcurrentHashMap 으로 선언하였습니다.
- compute 메서드에서 사용되는 CAS 알고리즘을 통해서 쓰기 작업에서 데이터 정합성을 보장할 수 있습니다.
- 주문 이력을 관리하기 위해 주문 정보를 담을 수 있는 클래스를 작성하였습니다.
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