HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
📝
남득윤 학습 저장소
/
🧵
멀티쓰레드, 동시성 프로그래밍
/
⚠️
멀티 쓰레드 프로그래밍 주의 사항
⚠️

멀티 쓰레드 프로그래밍 주의 사항

@참고)
  • 박철우 - 자바 volitile 키워드
  • JS - Java - AtomicInteger 사용 방법

문제상황

  • DeadLock
    • 두개 이상의 쓰레드가 자원을 소유한 상태로 서로가 소유한 락을 읽어오기 위해 경쟁하는 상태
  • LiveLock
    • 한 쓰레드가 이미 자원을 점유한 상태에서 다른 쓰레드가 그 자원을 사용하기 위해 무한정 대기상태에 빠지는 상태
  • Starvation
    • 다른 쓰레드가 락을 해제하지 않아 쓰레드가 임계영역에 진입하지 못하는 상태
  • 쓰레드 간섭 → 동시성 문제 : Race Condition, Visibility Problem
    • 하나의 자원에 여러 쓰레드가 사용하고자 할때 발생하는 문제
    • 쓰레드 간섭은 서로 다른 쓰레드에서 두 연산이 동시에 실행되어 상태가 꼬이는 것
    • int i = 5; Thread 1 : i++; // reads value 5 Thread 2 : i++; // reads value 5 Thread 1 : // increments i to 6 Thread 2 : // increments i to 6 // i == 6 instead of 7
      i++ is not atomic!
      notion image

해결방법

  • 운영 체제에서 동시성 문제를 예방하는 방법
    • Bounded Waiting (DeadLock, Starvation 예방)
    • Progress (LiveLock 예방)
    • Mutual Exclusion (Race Condition, Visibiality Problem 예방)
      • Mutex, Semaphore
 
  • 자바에서 동시성 문제를 해결하는 방법
  1. volatile 키워드
      • volatile 키워드는 변수의 값을 저장할 때 cpu 캐시가 아닌 메인메모리에 직접 쓰기 작업을 수행 하고 변수의 값을 읽을 때도 메인메모리에서 직접 읽어 올것을 명시하는 키워드 입니다.
      • 따라서 Thread 1 에서는 쓰고 Thread 2 에서는 읽는 경우에 voliatile 키워드는 동시성을 보장합니다.
      • 하지만 volatile 키워드를 사용하여 Main Memory로 부터 변수를 읽기/쓰기하는 것은 CPU 캐시를 활용하는 것 보다 많은 비용이 요구됩니다. volatile 의 선언은 JVM 의 성능 향상 기술인 코드 재정리를 막기도 합니다.
      • 따라서 volatile 키워드는 변수의 visiablity 보장이 반드시 필요한 상황에 신중하게 사용해야합니다.
 
  1. synchronized 키워드
      • synchronized 키워드는 메서드, 변수 혹은 코드 블럭에 선언하여 다른 쓰레드의 해당 영역으로의 진입을 막는 역할을 할 수 있습니다.
      • 안전하지만 가장 비용이 큽니다.
 
  1. java.util.concurrent 패키지의 atomic data type
      • e.g.) AtomicInteger, AtomicLong, …
      • Atomic 클래스는 Compare-and-Swap 을 기용하여 동시성을 보장합니다.
      • 여러 쓰레드에서 데이터를 write 해도 문제가 없습니다.
      • Atomic 클래스는 synchronized 보다 적은 비용으로 동시성을 보장할 수 있습니다.
 
  1. 스트림 API 활용
 
@See Also)
  • 쓰레드가 공유하는 자원에 대한 동시성을 해결하기 위한 위 방법들과는 별개로쓰레드가 자신의 고유한 자원을 보장받기 위해 사용하는 ThreadLocal 이라는 개념도 알아둡시다.
    🧵
    ThreadLocal
    Java ThreadLocal