티스토리 뷰

반응형

솔직히 이건 너무했다.. 좋은 점이 너무 많아진 자바 19 버전입니다.

자바 19버전은 최근 (2022년 9월 20일)에 릴리즈되었습니다. 아직 사용하고 있는 실제 사례가 거의 없고, 업그레이드를 진행하지 않아 사용 불가능한 문법이 다소 있지만, 앞으로 사용해보면서 좋은 점을 하나씩 곱씹어가보면서 알아가야 되지 않을까 합니다.

아래에는 여러 문서들을 참조하여 나름 커스텀해서 이해하기 쉽도록 샘플 코드를 몇 개 작성해보았습니다. 자바 19를 입문하는데 도움이 되었으면 좋겠습니다.

 


 

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

 

위 글을 참조해서 작성하면 좋은 점은 크게 3가지이고, 그 외에 소소한 부분도(소소하지 않을수도..) 많이 개선되었습니다!

 

1. 동시성

이전에 우리는 Stream 이라는 Functional Interface 를 통하여 List,Array에 대한 컨트롤을 진행했습니다. 또는 for loop 을 이용하여 발생하는 비용은 O(n)의 시간복잡도를 이용하여 단일 쓰레드 방식으로 작동하곤 하였습니다. 하지만 이 내용이 자바 19부터 멀티 쓰레드를 활용하는 것이 기본값으로 설정되어 처리되도록 구성되었습니다.

public UserResponse handle() throws ExecutionException, InterruptedException {
   try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { // 동시적으로 진행하여
       Future<String> user = scope.fork(() -> findUser()); // 사용자를 조회합니다.
       Future<Integer> order = scope.fork(() -> fetchOrder()); // 그러면서 동시에 주문을 넣습니다.
       
       scope.join();   // 해당 메소드를 통해 두 가지를 동시성 제어가 가능하게 합니다.
       scope.throwIfFailed();  // 에러가 발생하면 전파합니다.
       
       return new Response(user.resultNow(), order.resultNow());
   } catch (ExecutionException | InterruptedException e) {
       log.error(e.getMessage());
       throw e;
   }
}

 

2. 쉬운 record 캐스팅

먼저 소스를 보겠습니다. 

record Rectangle(int width, int height) {} // Java 14 에서 나온 record 입니다. dataclass 로 유명합니다.
record Triangle(int a, int b, int c) {} 

// 모든 변의 길이 합을 구하는 함수
int getLineSum(Object o) { // 파라미터가 Object 입니다.
   if(o instanceof Rectangle(int width, int height)) {
       return (width + height) * 2; // 직사각형의 가로길이와 세로길이에 2를 곱한 값
   } else if (o instanceof Triangle tri) {
       return tri.a + tri.b + tri.c; // 삼각형의 세 변의 길이 합을 구합니다. 피타고라스는 우선 무시..
   }
   return 0;
}

record 클래스에 준하여 instanceof 로 들어온 파라미터의 클래스를 확인한 다음, 각 변의 길이 합을 구하는 함수를 작성해보았습니다. 

이전에 작성한 코드와 비교하여 바로 파라미터로 들어온 값들을 구할 수 있는 것이 정말 편해졌습니다. 이전에는 Rectangle rect = (Rectangle) o; 와 같은 형식으로 선언 및 형변환을 진행했다면 이번에는 타입이 확실하기 때문에 바로 접근할 수 있습니다.

 

3. 가상 멀티 쓰레드(들)

1번과 이어지는 내용이지만 기존에 쓰레드는 운영 체제에서 관리하며 많은 리소스를 사용하였습니다. 하지만 이제 지원하는 내용은 쓰레드를 컨트롤하는 데 리소스가 많이 감소하여 동시적으로 병렬 쓰레드를 수행하여도 많이 문제가 없도록 성능이 개선되었습니다. 

try (var e = Executors.newVirtualThreadPerTaskExecutor()) {
    IntStream.range(0, 1_000).forEach(i -> {
       e.submit(() -> {
          Thread.sleep(Duration.ofSeconds(1));
          return i;
       });
    });
} // e.close() 함수가 무조건 호출됩니다.

 

4. Foreign Function 

public class FFMTest {
  public static void main(String[] args) throws Throwable {
    // 1. Get a lookup object for commonly used libraries
    SymbolLookup stdlib = Linker.nativeLinker().defaultLookup();

    // 2. Get a handle to the "strlen" function in the C standard library
    MethodHandle strlen = Linker.nativeLinker().downcallHandle(
        stdlib.lookup("strlen").orElseThrow(), 
        FunctionDescriptor.of(JAVA_LONG, ADDRESS));

    // 3. Convert Java String to C string and store it in off-heap memory
    MemorySegment str = implicitAllocator().allocateUtf8String("Happy Coding!");

    // 4. Invoke the foreign function
    long len = (long) strlen.invoke(str);

    System.out.println("len = " + len);
  }
}

이제 자바에서 지원하지 않았던 함수들을 가져와 사용할 수 있습니다. 아무래도 '외래 함수'라고 표현하는 것이 맞을 것 같습니다. 위의 소스코드는 C언어에서 사용하는 stdlib.c 의 내용을 가져왔습니다. 

 

5. Vector API 

기존에 사용했던 java.util.Vector 와는 상관 없는 새로운 벡터 API를 제공합니다. 아래 내용은 번역본이라 조금 부자연스러울 수 있지만, 벡터의 특징 상 매우 빠른 연산과 처리가 가능합니다. 기존과는 다른 퍼포먼스의 성능을 제공한다고 합니다.

더보기

새로운 벡터 API는 java.util.Vector 클래스와 아무 관련이 없습니다. 사실, 그것은 수학적 벡터 계산을 위한 새로운 API와 최신 SIMD(Single-Instruction-Multiple-Data) CPU로의 매핑에 관한 것이다.

벡터 API는 자바 16부터 인큐베이터로 JDK의 일부였으며 자바 17과 자바 18에서 더 개발되었다.

JDK Enhancement Proposal 426을 통해 Java 19는 API가 새로운 벡터 작업을 포함하도록 확장된 네 번째 반복과 벡터를 저장하고 메모리 세그먼트에서 읽을 수 있는 기능(외국 함수 및 메모리 API의 기능)을 제공합니다.

인큐베이터 기능은 여전히 크게 변경될 수 있으므로 여기에서 API를 자세히 제시하지 않을 것입니다. 벡터 API가 미리보기 단계로 이동하자마자 그렇게 할 것이다.

 

6. 패턴 매칭 Switch 문

switch (obj) {
  case String s && s.length() > 5 -> System.out.println(s.toUpperCase());
  case String s                   -> System.out.println(s.toLowerCase());

  case Integer i                  -> System.out.println(i * i);

  default -> {}
}

이전보다 강력한 switch 문을 제공합니다. 이전에는 무조건 타입이 맞아야하거나 Enum 클래스를 switch (enum) 의 형태로 넣어서 형을 변환해가면서 사용하는 불편함이 있었지만, 이제 그럴 필요 없이 패턴을 바꿔가면서 switch 구문을 활용할 수 있게 변경되었습니다.

 

Reference : https://www.happycoders.eu/java/java-19-features/#Foreign_Function_Memory_API_Preview_-_JEP_424

 

Java 19 Features (with Examples) - HappyCoders.eu

The new Java 19 features with examples: Virtual Threads (preview), Record Patterns (preview), Foreign Function & Memory API (preview) + more

www.happycoders.eu

 

반응형
댓글
공지사항