Projects/HubEleven

[동시성 처리] Java 에서 발생하는 동시성 문제란?

annovation 2026. 2. 4. 22:04

Java 동시성 문제 (Race Condition, 레이스 컨디션)

💡Java 동시성 문제란?

  • Java에서 여러 스레드가 같은 데이터(필드/객체 상태) 를 공유하며 실행될 때, 올바른 제어 없이 접근하면 오류가 생긴다.
  • 이렇게 여러 스레드가 공유 메모리(객체, 필드, 배열 등)에 접근할 때 명확한 동기화 규칙이 없어서, 값이 다르게 보이거나 실행 순서가 뒤틀리는 현상을 뜻한다.

💡동시성 문제가 발생하는 이유

 

1) Thread interference (스레드 간 간섭)

  • 여러 스레드가 같은 데이터에 접근/수정하면서 연산이 서로 끼어들어 결과가 깨지는 문제 (전형적인 race condition의 형태)
  • Java의 모든 객체의 필드, static 변수, 배열 요소는 힙 메모리에 존재하는데, 이 영역은 여러 스레드가 동시에 읽고, 쓸수 있기 때문에 접근 순서를 규정하지 않으면 문제가 발생한다. (§17.4.1 Shared Variables)

2) Memory consistency errors (메모리 일관성 오류)

  • 한 스레드가 쓴 값이 다른 스레드에서 제때 보이지 않거나(stale), 실행 순서가 기대와 다르게 관찰되는 문제(가시성/순서 문제)
  • (§17.4 Memory Model, §17.4-A/B 예제)

멀티스레드로 처리할 때 레이스 컨디션이 일어나는 이유

💡예상 작업 순서

Thread-1 Stock Thread-2
select *from stockwhere id = 1 {id: 1, quantity: 5}  
update set quantity = 4from stockwhere id = 1 {id: 1, quantity: 4}  
  {id: 1, quantity: 4} select *from stockwhere id = 1
  {id: 1, quantity: 3} update set quantity = 3from stockwhere id = 1
  • Thread-1 이 데이터를 가져가 update 한 값을 Thread-2 가 가져간 이후 update 하는 것을 예상

💡실제 작업 순서

Thread-1 Stock Thread-2
select *from stockwhere id = 1 {id: 1, quantity: 5}  
  {id: 1, quantity: 5} select *from stockwhere id = 1
update set quantity = 4from stockwhere id = 1 {id: 1, quantity: 4}  
  {id: 1, quantity: 4} update set quantity = 4from stockwhere id = 1
  • 하지만, 실제로는 Thread-1 이 데이터를 가져가 update 하기 전에 Thread-2 가 값을 읽고 각각 update 를 수행하면서 한 쪽 변경이 덮어써지는 Lost Update 가 발생한다.

출처

1) Oracle Docs : Synchronization

https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html

 

Synchronization (The Java™ Tutorials > Essential Java Classes > Concurrency)

The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Dev.java for updated tutorials taking advantag

docs.oracle.com

2) Oracle Docs : Chapter 17. Threads and Locks

https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html

 

Chapter 17. Threads and Locks

class A { final int x; A() { x = 1; } int f() { return d(this,this); } int d(A a1, A a2) { int i = a1.x; g(a1); int j = a2.x; return j - i; } static void g(A a) { // uses reflection to change a.x to 2 } } In the d method, the compiler is allowed to reorder

docs.oracle.com

3) 블로그 : 재고시스템으로 알아보는 동시성 이슈 해결방법 1

https://velog.io/@kdmin0706/Java-Spring

 

[Java & Spring] 재고시스템으로 알아보는 동시성이슈 해결방법(1)

인프런 "재고시스템으로 알아보는 동시성이슈 해결방법" 강의를 듣고 작성한 글입니다. 동시성 문제란!? 동일한 데이터에 2개 이상의 스레드 혹은, 세션에서 가변 데이터를 동시에 제어할 때 나

velog.io

4) 블로그 : [재고시스템으로 알아보는 동시성 이슈 해결방법] #2 재고감소 로직 작성 및 테스트

https://dev-rosiepoise.tistory.com/129

 

[재고시스템으로 알아보는 동시성 이슈 해결방법] #2 재고감소 로직 작성 및 테스트

들어가기 전 ..1. 이전 게시글과 이어지는 게시글이므로 프로젝트 환경 및 세팅은 아래 링크에서 확인해주세요!2. 전체 코드는 아래의 Git에서 확인 가능합니다!참고하면 좋을 이전 글 [재고시스

dev-rosiepoise.tistory.com