반응형

Java에서는 변수나 메서드, 클래스의 동작 방식을 제어하는 다양한 키워드가 존재합니다. 이 중에서도 volatile, transient, synchronized는 각각 메모리 동기화, 직렬화, 그리고 스레드 동기화와 관련된 중요한 역할을 합니다.


volatile 키워드

volatile은 멀티스레드 환경에서 변수의 값을 메인 메모리에 직접 저장하고, 모든 스레드가 항상 최신 값을 읽도록 보장하는 역할을 합니다.

적용 대상 변수
주요 기능 캐시된 값을 사용하지 않고 항상 메인 메모리의 최신값을 읽음
주로 사용하는 경우 스레드 간 변수 값 공유 시 데이터 일관성 유지
public class SharedData {
    private volatile boolean flag = false;

    public void writer() {
        flag = true; // 값 변경 시 바로 메인 메모리에 반영
    }

    public void reader() {
        if (flag) {
            // flag가 true로 바뀌면 반드시 이 코드가 실행됨
        }
    }
}

 

단, volatile원자적 연산(atomic operation)을 보장하지 않으므로, 복합 연산이 필요하면 synchronized를 함께 사용해야 합니다.


transient 키워드

transient 키워드는 Java 기본 직렬화(ObjectOutputStream 등) 과정에서 특정 필드를 직렬화 대상에서 제외하고자 할 때 사용합니다.
즉, 직렬화 시점에 해당 필드는 저장되지 않으며, 역직렬화 후에는 기본값으로 초기화됩니다.

적용 대상 변수
주요 역할 Java 기본 직렬화 시 필드 제외

 

class User implements Serializable {
    String username;
    transient String password; // Java 직렬화 시 제외
}

transient 키워드 vs @JsonIgnore 어노테이션

구분 transient @JsonIgnore
적용 대상 변수 변수, 메서드
직렬화 대상 Java 기본 직렬화 (ObjectOutputStream) JSON 직렬화/역직렬화 (Jackson, Gson 등)
주요 역할 직렬화 시 필드 제외 JSON 변환 시 필드 제외
사용 시점 Java 직렬화를 직접 사용하는 경우 REST API JSON 응답/요청 시 민감 데이터 숨길 때
사용 예시
transient String password;
@JsonIgnore
private String password;
비고 Java 기본 직렬화에 한함 JSON 변환 제어에 특화

 

실무에서는 REST API 응답 시 민감 정보를 숨기기 위해 @JsonIgnore를 많이 사용하며, Java 기본 직렬화 목적이라면 transient를 사용합니다.


synchronized 키워드

synchronized는 멀티스레드 환경에서 임계 영역(critical section)을 보호하여, 동시에 한 스레드만 접근 가능하도록 하는 동기화 기능을 제공합니다.

적용 대상 메서드, 코드 블록
주요 기능 스레드 간 동시 접근 방지 및 데이터 일관성 유지
사용 목적 공유 자원 접근 시 레이스 컨디션 예방

 

public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++; // 이 메서드는 한번에 한 스레드만 접근 가능
    }

    public int getCount() {
        return count;
    }
}

또는 특정 코드 블록만 동기화할 수도 있습니다.

public void add(int value) {
    synchronized(this) {
        count += value;
    }
}

주의할 점은 동기화 과도 사용 시 성능 저하가 발생할 수 있으므로, 필요한 부분에만 최소한으로 적용하는 것이 좋습니다.


요약 비교표

키워드 적용 대상 주요 역할 사용 시기
volatile 변수 메인 메모리와 변수 값 동기화, 최신 값 보장 멀티스레드 변수 값 공유 시
transient 변수 Java 기본 직렬화 시 필드 제외 객체 직렬화 시 제외 필드 지정
synchronized 메서드, 블록 임계 영역 보호, 동시 접근 방지 멀티스레드 환경에서 데이터 무결성 필요할 때

 


실무 팁

  • volatile는 원자적 연산이 아닌 단순 값 변경 공유에 적합하며, 복합 연산은 synchronized를 병행 사용하세요.
  • transient@JsonIgnore는 각각 직렬화 환경(Java 기본 직렬화 vs JSON)에서 필드 제외를 위해 사용하므로, 목적에 맞게 선택해야 합니다.
  • synchronized는 꼭 필요한 부분에 최소한으로 사용해 성능 저하를 방지하세요.

마무리

Java의 volatile, transient, synchronized 키워드는 모두 멀티스레드 처리, 직렬화, 데이터 일관성 유지 등에서 매우 중요한 역할을 합니다.
각 키워드가 가진 특징과 차이점을 이해하고, 상황에 맞게 적절히 활용하는 것이 안정적이고 효율적인 Java 프로그래밍의 핵심입니다.

반응형

+ Recent posts