JDK21 Structured Concurreny-(1)

woozi
8 min readFeb 5, 2024

--

JDK 21 Preview Features, Structured Concurrency

https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/

이번 포스팅은
JDK21 Preview 기능인 Structured Concurreny 에 대해서 소개하고자 합니다.
2024년 게으른 개발자 컨퍼런스에 발표한 자료가 있으니 참고해도 좋습니다.

# Structured Programming

Structured Programming(구조적 프로그래밍) 은
1960년 후반부터 1970년 초에 등장한 프로그래밍 패러다임 개념으로
Corrado Böhm’ 이라는 교수의 논문으로부터 시작되었습니다.

Structured Programming 은 대표적인 프로그래밍 패러다임 3가지 중 하나로
Object-oriented programming, Functional Programming 에 비해
비교적 늦게 등장했지만 가장 빠르게 널리 도입된 특이한 이력이 있습니다.

가장 빠르게 널리 도입되었다는 의미는
많은 이들을 납득시키고 그 유효성을 입증시켰다는 것을 의미하는데요.
Structured Concurrency 의 전신인 Structured Programming 은
과연 무엇인지 이번 포스팅에서 간단히 언급하고자 합니다.

## goto is harmful

Structured Programming 등장 배경에 대해서 설명할 때
goto 를 빠뜨릴 수 없습니다.

https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/

goto 는 특정 위치로 실행 흐름을 바꾸기 위해 사용하는 명령어입니다.
주로 저수준 언어들에서 사용하며,
현대 언어들에서도 제한적이게 사용하거나 예약어 등으로 남아있습니다.

익히들 goto 사용에 대해서 권장하지 않는데, 크게 2가지 이유에서입니다.

  1. 스파게티 코드 작성
  2. 추상화 파괴

실행 흐름을 유기적으로 변경할 수 있다는 것은
개발자는 모든 실행 흐름에 대해서 파악할 필요성이 있다는 것을 의미합니다.이를 지키지 않을 경우 개발자는 복잡한 로직을 설계하게 될 것이고
이는 곧 버그를 유발할 수 있는 환경을 조성하는데 기여할 것입니다.

https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/#go-statement-considered-harmful

이 같은 문제에 대해서 Edsger W. Dijkstra
ACM 학회에 한 서한을 보냈는데 전반적인 내용은 아래와 같습니다.

  1. GOTO 문이 프로그램의 흐름을 복잡하게 만들고,
    이로 인해 프로그램이 이해하기 어렵고 오류가 발생하기 쉬워진다.
  2. 정적 프로그램과 동적 프로세스 사이의 개념적 간극을 줄이고,
    이에 대한 대응을 가능하면 작게 만들기 위해서 최선을 다해야 한다.
  3. 조건문과 반복문 같은 구조적 기법을 사용하여
    프로그램을 더 명확하고 관리하기 쉽게 만들어야 한다.
  4. 이러한 접근 방식은 프로그램의 신뢰성과 유지보수성을 향상시킬 것이다.

서한이 공개되고 난 후, 개발자들 사이에서는 많은 논쟁들이 있었으나
결과적으로 ‘Strctured Programming’ 발전에 막대한 영향을 주었습니다.
그리고 이 서한의 제목은 ‘유해한 것으로 간주됨’ 밈으로유명한
Go To Statement Considered harmful 입니다.

참고로, Edsger W. Dijkstra 는 Ole-Johan DahlC. A. R. Hoare 함께
1972년, Strctured Programming 이란 책의 공동 저자로서 참여했으며
동일 년도 “컴퓨터 과학의 노벨상”으로 불리는 튜링상을 타기도 했습니다.

그렇다면 Edsger W. Dijkstra 가 주장하는
‘Structured Programming’ 의 핵심 아이디어는 무엇일까요?

코드의 실행 흐름은 순차적으로 흐르며, 실행 흐름이 나뉘어지더라도
본래의 흐름으로 돌아올 수 있는
구조적인 형태를 갖추는 것입니다.

구조적인 형태는 본래의 흐름으로 돌아오는 것을 보장해주고 있습니다.
나뉘어진 실행 흐름들이 어떻게 구성되어있는지
그 세부적인 내용들에 대해서 알 필요가 없어졌으며
이는 곧 추상화가 가능해졌다는 것을 의미합니다.

## go statement is harmful

오늘날 ‘Structured Programming’은 잘 이루어지고 있는 것일까요?
2000년대 초, Multi Core / Multi Threading 이 도입되면서
다수의 스레드들을 기반으로 동시성 코드를 작성할 수 있게 되었습니다.

go myfunc()

대표적인 케이스로, go 언어의 goroutin 호출 코드를 살펴보겠습니다.

https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/

부모 고루틴 흐름은 순차적인 구조로 위에서 아래로 흐르고 있지만
새로 생성된 자식 고루틴은 실행 흐름이 분기되어
독자적인 흐름을 가지는 것을 확인할 수 있습니다.

https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/

결과적으로 go 는 goto 와 매우 유사한 형태를 띄고 있습니다.

Strcutured Concurreny 를 널리 유행시킨
Nathaniel J. Smit 는 이같은 형태에 대해서
다익스트라의 서한 제목을 오마주한
Go Statement Considered harmful 라고 언급합니다.

실제로 동시성 프로그램은 별개의 독자적인 흐름을 갖기 때문에
코드를 작성하고 추론하기가 매우 어려운 단점이 있습니다.(디버깅 등)

Java 에서도 마찬가지입니다. Thread/Futre/CompletableFutre 활용시
부모 스레드와 자식 스레드가 별개로 동작하는 것을 쉽게 볼 수 있습니다.
코드는 ‘구조적’인 것처럼 보이지만, ‘실행 흐름’은 구조적이지가 않습니다.

‘비구조적 형태’는 추상화를 어렵게 만들거나 이를 파괴할 수 있습니다.
(무조건은 아닙니다.)

그렇다면, 구조적인 형태를 접목 시켜보면 어떨까요?
하위 스레드 그리고 그 하위 스레드들의 하위 스레드가 무수히 생성되더라도
결국 본래의 상위 스레드로 흐름으로 돌아오는 것을 보장해주기 때문에
추상화를 적용할 수 있을 것 같습니다.

이것이 앞으로 설명드릴 Structured Concurrency, 구조적 동시성입니다.

--

--