synchronized 키워드를 사용하면, 멀티 스레드 환경에서 Race Condition을 해결해주는 지 확인해보자.
Q. Race Condition이란?
여러 스레드 또는 프로세스가 동시에 실행되면서 동일한 자원에 접근하거나 변경을 시도할 때 발생하는 문제이다.
프로그램의 동작이나 결과는 실행 순서에 따라 달라질 수 있으며, 예상치 못한 버그나 비정상적인 동작을 유발할 수 있다.
@Test
package com.example.payment.test;
import static org.assertj.core.api.Assertions.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.jupiter.api.Test;
public class synchronizedTest {
private int value = 0;
public void increase() {
value += 1;
}
@Test
void 동기화_처리_안한_경우() throws Exception{
//given
ExecutorService service = Executors.newCachedThreadPool();
CountDownLatch latch = new CountDownLatch(100);
//when
for(int i = 0; i < 100; i++) {
service.submit(() -> {
try {
increase();
} finally {
latch.countDown();
}
});
}
//then
assertThat(value).isEqualTo(100);
}
}
@Test 출력 결과
100번 increase 메서드를 호출했는데, 100이 출력되는 것이 아닌, 74가 출력되었다. 멀티 스레드로 increase() 메서드를 호출해주기 때문에 동시성 문제가 발생했다.
Synchronized 키워드 적용
package com.example.payment.test;
import static org.assertj.core.api.Assertions.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.jupiter.api.Test;
public class synchronizedTest {
private int value = 0;
public synchronized void increase() {
value += 1;
}
@Test
void 동기화_처리_안한_경우() throws Exception{
//given
ExecutorService service = Executors.newCachedThreadPool();
CountDownLatch latch = new CountDownLatch(100);
//when
for(int i = 0; i < 100; i++) {
service.submit(() -> {
try {
increase();
} finally {
latch.countDown();
}
});
}
latch.await();
//then
assertThat(value).isEqualTo(100);
}
}
@Test 출력 결과
아래 테스트 결과는 동기화 처리를 한 후에 돌린 테스트 결과이다.
synchronized 키워드를 통해 공통 변수인 value에 대해 동기화를 해주어서, 올바른 테스트 결과가 나오게 되었다.
'Java' 카테고리의 다른 글
Object.equals() 메서드가 정말 null-safe한가? (0) | 2024.09.25 |
---|---|
equals()메소드를 비교하는 대상이 null인 경우 (0) | 2024.09.25 |
@SoftAssertions를 사용하는 이유 (0) | 2024.07.17 |
@NotBlank과 @NotNull를 사용하는 이유 (0) | 2024.07.17 |
BigDecimal의 compareTo 메서드 파헤치기 (0) | 2024.07.17 |