[원문] https://tomaszs2.medium.com/java-19-is-a-game-changer-21f5f48d239b
Java 19 Is A Game Changer
Users of Java programming language can celebrate. After LTS 17, the new version offers concise and easy to use solutions for problems other…
tomaszs2.medium.com
Java 언어 사용자들은 축하하자. LTS 17 버전 이후로, 새로운 버전은 다른 언어들이 무시하거나 어려움을 겪는 문제들에 대한 간단하고 쉬운 해결책을 제공한다.
동시성
StructuredTaskScope라는 새로운 형태는 동시성을 다루는 코드 조각이다. 동시성에 대한 이 접근법은 코드가 어떻게 동작할지를 매우 분명하게 보여줄 뿐만 아니라, 코드를 명확하고 읽기 쉽게 만들어준다.
Response handle() throws ExecutionException, InterruptedException {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Future<String> user = scope.fork(() -> findUser());
Future<Integer> order = scope.fork(() -> fetchOrder());
scope.join(); // 두 fork를 기다린다
scope.throwIfFailed(); // 에러가 발생한 경우 에러를 전파한다
// 두 fork가 성공했으므로, 결과를 합친다
return new Response(user.resultNow(), order.resultNow());
}
}
멋진 결과지만, 제일 중요한 부분은 끝에서 설명한다.
단순해진 조건부 record 캐스팅
Java 19에서 사용할 수 있는 record 패턴 기능 프리뷰는 타입 체크와 캐스팅을 한 줄에 처리하는 문법을 도입했다.
record Point(int x, int y) {}
void printSum(Object o) {
if (o instanceof Point(int x, int y)) {
System.out.println(x + y);
}
}
또한, switch의 패턴 매칭에 대한 세 번째 프리뷰가 이번 릴리즈에 포함되었다.
이러한 변화들은 놀랍지만, 마지막이 진짜다.
가상 스레드
다양한 운영체제의 스레드는 주의가 필요하며, 많은 리소스를 사용한다. 최신 Java는 서버의 동시성 작업을 획기적으로 개선할 수 있는 대안에 대한 프리뷰를 제공한다. 이것은 가상 스레드라고 부른다.
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(Duration.ofSecond(1));
return i;
});
});
} // executor.close()는 내부적으로 호출되고, 종료를 기다린다
Java 19의 다른 변화들:
- 외부 함수 & 메모리 API 프리뷰
- 벡터 API의 네 번째 인큐베이션
[더 알아보기] https://www.infoworld.com/article/3653331/jdk-19-the-new-features-in-java-19.html
내용 추가
Structured Concurrency
먼저, 본문의 예시를 Structured Concurrency를 사용하지 않는 코드로 고쳐보자.
Response handle() throws ExecutionException, InterruptedException {
try (ExecutorService executorService = Executors.newFixedThreadPool(2)) {
Future<String> user = executorService.submit(() -> findUser());
Future<Integer> order = executorService.submit(() -> fetchOrder());
String userValue = user.get();
Integer orderValue = order.get();
return new Response(userValue, orderValue);
}
}
얼핏 보면 문제가 없어보이지만, user나 order를 실행 중에 예외가 발생하는 경우가 문제다. 만약 user.get()으로 기다리는 동안 order에서 예외가 발생할 경우 user의 진행을 멈추고 빠르게 종료하는 것이 효율적이다. 그러나 위의 코드는 user.get()이 반환하기를 기다렸다가 order.get()에서 예외를 던진다.
또한, handle 메소드가 실행되고있는 스레드가 종료되는 경우에도 user와 order는 계속 실행될 것이다. 이렇게 예외가 발생하는 경우에 본문과 같이 Structured Concurrency를 사용하면 예외를 전파하고 빠르게 종료할 수 있다.
[참고] https://www.baeldung.com/java-structured-concurrency
Switch-case
Java 17에서는 서브클래스 타입으로 매칭할 수 있었다. 또한 아래 예시처럼 o는 i, l로 자동 캐스팅된다.
public String match(Object o) {
return switch(o) {
case Integer i -> "Integer value = " + i;
case Long l -> "Long value = " + l;
default -> "Not Integer";
};
}
본문의 예시와 비슷하게 record도 switch case로 매칭할 수 있고, when을 사용하면 조건을 추가할 수 있다.
record Point(int x, int y) {}
public String diamond(Point p) {
return switch(p) {
case Point(int x, int y) when x + y > 10 -> "Outside";
case Point(int x, int y) -> "Inside";
default -> "On the line";
};
}
가상 스레드
기존의 Java 스레드(Platform Thread)는 OS의 커널 스레드와 1:1로 매칭되었다. Java 19에 새롭게 도입된 가상 스레드는 플랫폼 스레드와 M:N의 관계이다. 소수의 플랫폼 스레드에 다수의 가상 스레드를 실행하도록 스케줄링한다. 요청당 1개의 스레드를 할당하는 서버 어플리케이션에서 처리량을 늘릴 수 있다.
[참고] https://medium.com/javarevisited/how-to-use-java-19-virtual-threads-c16a32bad5f7
외부 함수 & 메모리 API(Foreign Function & Memory API)
Java 런타임 외부의 코드와 상호작용할 수 있도록 지원하는 API이다. JNI의 단점을 보완하여 외부 함수와 외부 메모리에 안전하고 쉽게 접근할 수 있게 해준다.
[참고] https://openjdk.org/jeps/434
Vector API
CPU의 SIMD(Single Instruction, Multiple Data)를 이용해서 벡터 연산을 빠르게 할 수 있도록 제공하는 API이다. CPU의 아키텍처에 따라 내부적인 구현이 다르지만, 통일성있는 API로 제공하여 사용하기 쉽게 만들어준다.
[참고] https://medium.com/javarevisited/how-to-use-java-19-virtual-threads-c16a32bad5f7
'기타 > 번역' 카테고리의 다른 글
[번역] Java의 Exception을 사용하지 마! (0) | 2023.03.14 |
---|