OpenJDK Project Loom

gyubong park·2020년 11월 20일
0

Project Loom

자바 플랫폼에서 경량 동시성을 보장하는 새로운 프로그래밍 모델 지원 프로젝트
https://wiki.openjdk.java.net/display/loom/Main

프로젝트 구성
1. Virtual threads
2. Delimited continuations
3. Tail-call elimination

출처
http://gunsdevlog.blogspot.com/2020/09/java-project-loom-reactive-streams.html
http://guruma.github.io/posts/2018-09-27-Project-Loom-Fiber-And-Continuation/
https://developers.redhat.com/blog/2019/06/19/project-loom-lightweight-java-threads/


프로젝트의 동기

자바는 OS 스레드를 직접적으로 사용하지만 동시에 수천개의 요청을 효율적으로 처리하기 쉽지 않았음
그래서 나온 것들이 비동기 라이브러리, 하지만 자바의 스레드는 성능면에서 효율적이지 못했음
Loom의 목표는 경량 스레드를 어플리케이션 개발자들에게 제공하여 동기 블로킹 코드를 마음껏 이용하는데 있음

1. 사람들이 비동기 프로그래밍을 하는 이유

자바 MVC 스택은 기본적으로 쓰레드 풀, 즉 요청 하나당 하나의 스레드를 사용 (블로킹 방식)
그래서 많은 스레드를 사용하게 되고 이는 컨텍스 스위칭 비용을 유발
뿐만아니라 데르락, 스레드 누수 등의 문제 존재
반면, 비동기 프로그래밍은 적은 수의 스레드로 여러 요청을 처리, 자바의 동시성을 활용한 프로그래밍

2. 비동기 프로그래밍도 단점이 존재

  • 제어의 흐름을 잃음
    - 복잡한 콜백으로 인해 로직이 복잡함
  • 컨텍스트를 잃음
    - 스택 트레이스가 유지되지 않는다
  • 전염성이 있음
    - 한 메소드가 Future를 반환하면 다른 메소드도 Future를 반환해야 함, 특정 패러다임을 강제됨

3. 비동기 극복

동기함수에서는 비동기 함수 호출 불가
비동기에서 블록킹 IO 함수 호출에 신경써야 함 -> 적절한 스케줄링 필요
여전히 전염성이 있고 컨텍스트를 잃음


Project Loom

쓰레드가 블로킹 코드를 내부적으로 논블로킹으로 동작하게 하는 방식 사용
경량 쓰레드는 Continuations과 Schduler로 조합
Continuations : IO작업을 만나면 사용하던 쓰레드는 반납하고 현재 일한 상태로 있음, 나중에 호출되면 다시 그 시점부터 일함
Schduler : 스레드를 할당해줘서 잠시 멈춘 상태에서 다시 일을 하게 만듬

VirtualThread 유사 개념들

  • C++ - Boost.Fiber
  • Ruby - Fiber 클래스
  • Python - Greenlet
  • Go - goroutine
  • Javascript - Async/Await

참조 : http://guruma.github.io/posts/2018-09-27-Project-Loom-Fiber-And-Continuation/

경량쓰레드란 말을 쓰는데... 중량 스레드란?

java는 커널 쓰레드를 직접 가져와서 사용함
해당 쓰레드는 동시성 프로그래밍을 작성하기에 무겁다, 그래서 중량 쓰레드라고 한다
그러면 뭐가 무겁다는 것인가?

  • 리소스 부하가 많다
    - 스레드는 한 서바 당 수천개 밖에 만들지 못한다
    - 반면, 소켓은 수백만개를 생성할 수 있다
  • 동시성 작업 단위가 크다(사실 아래부분들 이해가 안됨)
    - 리소스 부하가 많다는 것과 연관
    - 동시성 프로그래밍은 그 어플리케이션의 특성에 따라 동시성의 작업 단위가 다름
  • 선점형 스케줄러
    - OS가 제공하는 커널 스레드는 선점형 스케줄러에 의해 처리된다는 사실
    - 선점형이란? 한 스레드에서 다른 스데르로 제어가 넘어가는 문맥전환이 전적으로 OS 담당
    - 따라서 어플리케이션 개발자가 쓰레드를 완변히 제어할 수 없다

경량 쓰레드

  • 매우 적은 리소스
    - 수백 바이트 정도
    - 스위칭 오버헤드는 거의 제로
    - 하나의 JVM에서 수백만 개 생성 및 원활한 동작 가능
  • synchronous, blocking 콜 가능
    - 성능 때문에 비동기 코드 작성 필요 없음
    - 동시성 프로그래밍이 단순해지며 또한 손쉽게 규모 확장이 가능
  • VirtualThread API들은 Thread 클래스와 거의 비슷
  • Serializable
  • Continuation
    - VirtualThread = Continuation + Scheduler
    - Scheduler는 기존의 ForkJoinPool을 그대로 사용
profile
초보 개발자

0개의 댓글