Java 25
얼마 전 Java 25와 관련한 내용들이 몇가지 공개되었다. 32bit 시스템에 대한 일부 지원 종료,GC의 변경사항 등 다양한 사항이 있었지만 그중 StableValue<> 클래스와 관련한 내용이 다수를 차지하였다.
StableValue<> ?
주어진 값이 최초 1회만 설정되고 이 이후로 변경되지 않도록 보장하는 자료형으로 불변성과 지연 초기화가 필요한 상황에서 유용하다. 즉, 일종의 불변 객체이다.
지연 초기화?
변수가 선언될 때 바로 초기화하는 것이 아니라 필요한 순간에 초기화 하는 것을 의미한다.
StableValue<T>가 도입되기 전에는 아래와 같은 방식으로 지연 초기화를 하며 불변성을 보장하여야 했었다.
private volatile String data;
public String getData() {
if (data == null) {
synchronized (this) {
if (data == null) {
data = "init";
}
}
}
return data;
}
StableValue<T>가 도입된 후에는 다음과 같이 간결하여졌다.
private final StableValue<String> data = new StableValue<>();
public String getData() {
return data.orElseGet(() -> "init");
}
기존 코드는 비동기적인 환경에서 동기적으로 작동하도록 설정하여 오버헤드가 발생할 위험성이 있고 코드 역시 복잡했으며 비동기를 직접 조정해야 한다는 치명적인 문제점이 있었지만 새로운 방식에서는 동기적으로 변경되지 않아도 되며 간단한 메서드 접근을 통하여 값을 제어할 수 있어 불변성을 보장하기 더 쉬워졌다.
주요 특징
- 1회만 값 설정 - StableValue<T>는 한번만 값을 설정할 수 있다. 값이 한번 설정된다면 이후엔 설정되지 않게 보장된다.
- 지연계산 - 값을 설정할 때 계산이 지연될 수 있다. 이를 통하여 자원을 절약하고 초기화 비용이 비싼 값을 효율적으로 관리 할 수 있다.
- 쓰레드 안정성 - 여러 쓰레드가 동시에 접근하더라도 한 번 설정된 값의 불변성이 보장되므로 동시성 문제를 피할 수 있다.
메서드
- trySet(T Value) - 값을 설정하려고 시도한다. 이미 값이 설정되어 있다면 진행되지 않고 false가 반환된다.
- setOrThrow(T Value) - 값을 설정하려고 시도하고, 이미 값이 설정되어 있다면 예외를 던진다.
- orElse(T defaultValue) - 값이 설정되지 않았을 경우 기본값을 반환한다.
- orElseThrow() - 값이 설정되지 않았을 경우 예외를 던진다.
사용예시
StableValue<String> stableValue = new StableValue<>();
stableValue.setOrThrow("Hello"); // 값 최초 설정
stableValue.setOrThrow("World") // 예외 발생(IllegalStateException)
사용할 만한 곳...?
1. 지연 초기화 - 초기화 비용이 비싼 연산을 1회만 수행하는 경우 등에서 사용할 수 있다.
StableValue<DatabaseConnection> connection = new StableValue<>();
connection.setOrThrow(createConnection()); // 첫 번째 접근 시 연결 설정
2. 멀티쓰레드 동시성 문제 - 멀티쓰레드 환경에서 환경변수 등의 최초 초기화 외엔 변경되면 안되는 값에서 여러 쓰레드가 동시에 접근해 값을 수정하지 못하도록 원천적으로 차단할 수 있다
StableValue<Config> appConfig = new StableValue<>();
appConfig.setOrThrow(loadConfig()); // 설정 값 한 번만 설정
3. 불변 객체 - 가장 기본적인 사용 시나리오로 값이 1회 설정 된 후 절대 변경을 하면 안될 때 사용할 수 있다
StableValue<User> user = new StableValue<>();
user.setOrThrow(new User("John", "Doe")); // User 객체는 한 번만 설정
4. 값 캐싱 - 초기화 비용이 비싼 값을 캐싱하여 한번만 계산하고 이후에는 동일한 값을 유지해야 하는 그런 요구사항에서 아주 유용하게 사용할 수 있다.
StableValue<HeavyComputationResult> resultCache = new StableValue<>();
resultCache.setOrThrow(performHeavyComputation()); // 계산된 결과는 한 번만 저장
마무리
Kotlin의 val이나 lateinit의 기능을 조합한 듯한 문법이다. 아직 Java 25는 개발 중이며 프레임워크가 이러한 문제를 해결해주기도 하지만 그래도 현대적인 비동기 프로그래밍 환경에서 간편하고 또한 성능적으로도 좋게 할 수 있는 문법이 나왔다는 점에서 Java 25를 주목할 만 하다 생각이 든다.
'Java' 카테고리의 다른 글
[Java] JavaDoc (0) | 2025.05.05 |
---|---|
[Java] Logging (0) | 2025.03.11 |
[Java] Ehcache (1) | 2024.12.05 |
[Java] 변수의 스코프(Scope) (0) | 2024.04.22 |
[Java] for each문 (0) | 2024.04.17 |