반응형
Thread-safe(스레드 안전)
- 여러 개의 스레드가 동시에 접근해도 문제가 발생하지 않도록 설계된 것
필요 이유
- 멀티스레드 환경에서는 여러 개의 스레드가 동시에 같은 데이터를 수정하려고 하면 Race Condition(경쟁 상태)가 발생할 수 있기 때문
- 예를 들어, 하나의 변수를 여러 스레드가 동시에 변경하려고 하면 의도하지 않은 값이 나올 수 있는 것
만드는 법
- synchronized 키워드 사용
- increment() 메소드를 한 번에 하나의 스레드만 실행할 수 있도록 synchronized를 추가하면 됨
class Counter { private int count = 0; public synchronized void increment() { // 동기화 count++; } public int getCount() { return count; } }
- synchronized를 사용하면 한 번에 하나의 스레드만 increment()를 실행할 수 있음
- AtomicInteger 사용
- 내부적으로 Thread-safe하게 동작하도록 설계되어 있기 때문에 동기화 없이도 안전하게 값을 증가할 수 있음
- AtomicInteger는 CAS(Compare-And-Swap) 기법을 사용하여 동기화 없이도 안전하게 동작
import java.util.concurrent.atomic.AtomicInteger;
class Counter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet(); // 원자적으로 증가
}
public int getCount() {
return count.get();
}
}
- Lock 사용(ReentrantLock)
- 더 정교한 스레드 동기화 제어 가능
- 반드시 lock.lock() 후 finally에서 lock.unlock()을 호출해야 함
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Counter {
private int count = 0;
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock(); // 🔒 락 획득
try {
count++;
} finally {
lock.unlock(); // 🔓 락 해제
}
}
public int getCount() {
return count;
}
}
- Thread-safe 컬렉션 사용
- Java에서는 ArrayList 같은 일반 컬렉션 클래스는 Thread-safe하지 않음
- 멀티스레드 환경에서 안전한 컬렉션을 사용하려면 ConcurrentHashMap이나 CopyOnWriteArrayList 같은 Thread-safe 컬렉션을 사용해야 함
import java.util.concurrent.CopyOnWriteArrayList;
public class ThreadSafeListExample {
public static void main(String\[\] args) {
CopyOnWriteArrayList list = new CopyOnWriteArrayList<>();
Runnable task = () -> {
for (int i = 0; i < 100; i++) {
list.add(i);
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("List size: " + list.size()); // 항상 정확한 값 출력
}
}
방법 | 설명 |
---|---|
synchronized | 간단하지만 성능 저하 가능성 있음 |
AtomicInteger | 원자적 연산을 제공하여 성능이 더 좋음 |
ReentrantLock | 동기화보다 유연한 제어 가능 (락 획득/해제) |
Concurrent Collections | 멀티스레드 환경에서 안전한 컬렉션 |
반응형
'JAVA' 카테고리의 다른 글
[JAVA] 원격 함수 호출(RMI, Remote Method Invocation) 완벽 정리 (1) | 2025.02.13 |
---|---|
[JAVA] 리플렉션(Reflection) 완벽 가이드 : 개념, 사용 이유, 활용, 단점 (0) | 2025.02.13 |
[JAVA] 익명 함수(Anonymous Function)와 람다 표현식 (1) | 2025.02.03 |
[JAVA] 동기와 비동기(Synchronous / Asynchronous) 완벽 가이드 : 실행 방식, 대기 여부, 복잡성 필교 (1) | 2025.02.03 |
Iterator, for문과의 차이 (1) | 2025.01.26 |