이 글은 원 저자 Jakob Jenkov의 허가로 포스팅된 번역물이다.

원문 URL : http://tutorials.jenkov.com/java-concurrency/index.html



 오래전 컴퓨터는 단일 CPU로 가동되고 한번에 한 프로그램만 실행할 수 있었다. 후에 멀티태스킹이 가능한 컴퓨터가 출현하였고, 여러 프로그램(작업 or 프로세스)을 동시에 실행하는 일이 가능해졌다. 사실 이 멀티태스킹은 엄밀히 말하면 '동시에' 실행되는 것이 아니었다. 여러 프로그램이 하나의 CPU를 공유하였고, 오퍼레이팅 시스템이 프로그램들 사이에서 아주 짧은 시간을 두고 포커스를 전환(switching)하는 원리였다.


멀티태스킹의 출현은 소프트웨어 개발자들에게 새로운 과제를 주었다. 하나의 프로그램이 더이상 CPU의 시간과 메모리, 리소스를 독점할 수 없게 되었고, '좋은 프로그램(A "good citizen" program)'이란 다른 프로그램들이 CPU의 자원을 활용할 수 있도록, 사용한 자원을 해제할 수 있는 것이어야 한다. 


지금의 멀티태스킹은 다수의 쓰레드가 같은 프로그램 안에서 실행되는 것이다. 한 쓰레드의 실행은 한 CPU가 실행중인 하나의 프로그램이라 할 수 있다. 당신이 한 프로그램을 실행하는 멀티쓰레드를 가질 때, 이것은 마치 다수의 CPU가 하나의 프로그램을 실행하는 것과 같은 일이 된다.


 어떤 프로그램들에게 멀티쓰레딩은 성능 향상에 있어 훌륭한 방법이 된다. 그러나, 멀티쓰레딩은 멀티태스킹과 다르고, 더 어려운 일이기도 하다. 하나 이상의 쓰레드는 한 프로그램 안에서 실행될 수 있고, 이런 이유로 읽기와 쓰기 작업이 같은 메모리에 동시에 발생된다. 이 현상은 싱글쓰레드 프로그램에선 보지 못했던 에러를 뱉어낼 수 있다. 이러한 에러들 중 몇몇은 싱글 CPU 머신에서는 좀처럼 보이지 않는데, 왜냐하면 이런 경우에는 두개의 쓰레드가 '동시에' 실행되는 일은 절대로 일어나지 않기 때문이다. 요즘의 컴퓨터는 멀티코어 CPU를 가지고 나오며, 아예 CPU 자체가 두 개 이상인 것들도 존재한다. 이것이 의미하는 바는 별개의 쓰레드들이  별개의 코어 혹은 CPU에서 동시에 실행될 수 있다는 것이다.



만일 하나의 쓰레드가 어떤 하나의 메모리 영역을 읽는데 다른 쓰레드가 이 영역에 쓰기 작업을 한다면, 첫번째 쓰레드가 읽게 되는 값은 어떤 것일까? 쓰기 작업 이전의 값? 두번째 쓰레드가 쓰기 작업을 마치고 난 다음의 값? 두가지가 섞인 어떤 값? 아니면, 두 쓰레드가 동시에 한 메모리 영역에 쓰기 작업을 한다면? 이 작업 뒤에는 어떤 값이 남겨질까? 첫번째 쓰레드의 값? 두번째 쓰레드의 값? 두 값이 섞인 값?


적절한 예방책이 없다면 이런 상황은 얼마든지 가능하며, 그 결과는 예상할 수 없을 것이다. 이 결과는 때에 따라 바뀔 수 있는 것이다. 때문에 개발자가 적절한 예방책을 숙지하는 것은 중요한 일이다 - 적절한 예방책을 숙지하는 일이란, 메모리, 파일, 데이터베이스 기타 등등 과 같은 공유된 자원을 쓰레드가 어떻게 접근하는지 컨트롤하는 방법을 배우는 것이다. 이것이 이 자바 컨커런시 튜토리얼이 다루는 토픽 중 하나이다.



자바의 멀티쓰레딩과 컨커런시


 자바는 개발자가 멀티쓰레딩을 쉽게 사용할 수 있게끔 만들어진 초기의 언어들 중 하나였다. 자바는 애초부터 멀티쓰레딩 능력을 가지고 있었는데, 때문에 자바 개발자들은 위에서 설명한 문제점들을 자주 직면한다. 이것이 내가 이 자바 컨커런시 코스(trail)를 작성이는 이유이다. 내가 그랬던 것처럼, 자바 개발자라면 누구나 이 코스에서 도움을 받을 수 있다.


이 코스는 주로 자바에서의 멀티쓰레딩에 관하여 다룰 것이지만, 멀티쓰레딩에서의 문제점들 중 몇가지는 멀티태스킹이나 분산처리 시스템 환경에서 발생되는 문제점들과 비슷하다. 때문에 멀티태스킹과 분산처리 시스템에 대한 레퍼런스도 존재할 것이다. 이런 이유로 '멀티쓰레딩' 보다는 '컨커런시' 가 더 어울린다.



2015년, 그리고 이후의 자바 컨커런시


 자바 컨커런시 서적이 처음 쓰여지고 자바 5 컨커런시 유틸리티가 배포된 이래로 컨커런트 아키텍처의 세계에는 많은 일들이 있었다. Vert.x와 Play / Akka and Qbit 과 같은 새로운, 비동기적인 'shared-nothing' 플랫폼과 API들이 나왔다. 이 플랫폼들은 스탠다드 자바/JEE의 쓰레딩 컨커런시 모델과는 다른 컨커런시 모델을 사용한다. 새로운 non-blocking 컨커런시 알고리즘이 발표되었고, LMax Disrupter 와 같은 새로운 non-blocking 툴들이 우리의 툴킷에 추가되었다. Fork/Join 프레임워크와 함께 새로운 함수형 프로그래밍 병행 구조가 자바 7 과 자바 8 의 컬렉션 스트림 API에 소개되었다.


나는 이 모든 새로운 개발물들과 함께 이 컨커런시 튜토리얼을 업데이트한다. 그러니까, 이 튜토리얼은 진행중 에 있다. 새 튜토리얼은 시간이 허락될 때면 언제든 개재될 것이다.



'Java > Concurrency' 카테고리의 다른 글

자바 쓰레드 시작하기  (0) 2017.04.09
컨커런시 vs. 페러럴리즘  (0) 2017.04.09
컨커런시 모델  (0) 2017.04.09
멀티쓰레딩의 단점  (0) 2017.04.09
멀티쓰레딩의 장점  (0) 2017.04.09

+ Recent posts