자바에는 이름이 비슷하게 들릴 수 있지만 전혀 다른 목적으로 사용되는 두 가지 키워드가 있습니다. 바로 volatile과 transient입니다. 이 글에서는 두 키워드의 개념, 차이점, 그리고 실제 사용 예제까지 자세히 살펴보겠습니다.
volatile 키워드란?
volatile은 멀티스레딩 환경에서 사용되는 키워드입니다. 여러 스레드가 동시에 같은 변수를 읽고 쓰는 상황에서, volatile로 선언된 변수의 변경 사항은 CPU 캐시에 머무르지 않고 메인 메모리에 즉시 반영됩니다. 덕분에 모든 스레드가 항상 최신 값을 읽을 수 있어 스레드 간 변수 가시성(visibility) 문제를 해결할 수 있습니다.
transient 키워드란?
반면 transient는 직렬화(Serialization) 과정에서 사용됩니다. transient로 선언된 필드는 직렬화 및 역직렬화 대상에서 제외됩니다. 즉, 특정 변수의 값을 저장하거나 전송하고 싶지 않을 때 해당 변수에 transient 키워드를 붙이면 됩니다. 대표적으로 비밀번호처럼 보안상 민감한 데이터나, 직렬화해도 의미가 없는 값에 활용됩니다.
volatile vs transient 핵심 차이점 비교
| 번호 | 구분 | volatile | transient |
|---|---|---|---|
| 1 | 기본 용도 | 변수의 변경 사항을 메인 메모리에 직접 반영하여 스레드 간 가시성을 보장합니다. | 직렬화 과정에서 해당 변수를 제외시킵니다. |
| 2 | 기본값 초기화 | 기본값으로 초기화되지 않습니다. | 역직렬화 시 기본값(default value)으로 초기화됩니다. |
| 3 | static 조합 | static 변수와 함께 사용할 수 있습니다. | static 키워드와 함께 사용할 수 없습니다. |
| 4 | final 조합 | final 키워드와 함께 사용할 수 있습니다. | final 키워드와 함께 사용할 수 없습니다. |
static과 final에 transient를 쓸 수 없는 이유
static 변수는 클래스 레벨에 속하므로 객체 직렬화 대상에 포함되지 않아 transient를 붙일 필요가 없습니다. 또한 final 변수는 선언 시 또는 생성자에서 값이 반드시 초기화되어야 하는데, 역직렬화 시 기본값으로 초기화되는 transient의 특성과 충돌하기 때문에 함께 사용할 수 없습니다.
transient 사용 예제
다음은 transient 키워드를 사용하여 특정 필드의 직렬화를 건너뛰는 샘플 클래스입니다.
// transient 키워드를 사용해 직렬화를 건너뛰는 필드를 가진 클래스
class TransientExample implements Serializable {
transient int age; // 직렬화에서 제외됨
// 나머지 필드는 정상적으로 직렬화됨
private String name;
private String address;
// 기타 코드
}volatile 사용 예제
다음 예제는 volatile 변수를 활용해 스레드를 안전하게 종료하는 전형적인 패턴을 보여줍니다.
class VolatileExample extends Thread {
volatile boolean isRunning = true;
public void run() {
long count = 0;
while (isRunning) {
count++;
}
System.out.println("스레드 종료. 카운트: " + count);
}
public static void main(String[] args) throws InterruptedException {
VolatileExample t = new VolatileExample();
t.start();
Thread.sleep(2000);
t.isRunning = false; // 다른 스레드에서 플래그 변경
t.join();
System.out.println("isRunning 값: " + t.isRunning);
}
}위 예제에서 isRunning 변수가 volatile이 아니라면, 메인 스레드가 값을 false로 변경해도 작업 스레드가 CPU 캐시에 저장된 이전 값(true)만 읽어 무한 루프를 빠져나오지 못할 수 있습니다. volatile 덕분에 변경된 값이 메인 메모리에 즉시 반영되어 스레드가 안전하게 종료됩니다.
정리
volatile은 멀티스레드 환경에서 변수의 가시성을 보장하는 키워드이고, transient는 직렬화에서 특정 필드를 제외하기 위한 키워드입니다. 두 키워드는 서로 다른 문제를 해결하며, 상황에 맞게 올바르게 사용하는 것이 중요합니다.