Java Concurrency는 Java 플랫폼에서의 멀티스레딩, 동시성 및 병렬 처리를 다루는 용어이다.
Java Concurrency Tutorial에서는 멀티스레딩, 동시성 구성, 동시성 문제점, 비용 등 Java 멀티스레딩 관련 이점의 핵심 개념을 다룰 것이다.
What is Multithreading?
멀티스레딩은 동일한 응용 프로그램 내에 여러 실행 스레드가 있음을 의미한다.
스레드는 응용 프로그램을 실행하는 별도의 CPU와 같다. 따라서 다중 스레드 응용 프로그램은 여러 CPU가 동시에 코드의 다른 부분을 실행하는 응용 프로그램과 같다.
단, 스레드는 CPU와 같지는 않다. 일반적으로 단일 CPU는 여러 스레드간에 실행 시간을 공유하여 지정된 시간동안 각 스레드 간에 전환이 일어나며, 응용 프로그램의 스레드가 다른 CPU에 의해 실행되도록 할 수 있다.
Why Multithreading?
응용 프로그램에서 멀티스레딩을 사용하는 것은 아래와 같은 이유들이 있다.
- 단일 CPU 사용률 향상
- 여러 CPU 또는 CPU 코어 사용률 향상
- 응답성과 관련하여 더 나은 사용자 경험
- 공정성과 관련하여 더 나은 사용자 경험
Better Utilization of a Single CPU
가장 일반적인 이유 중 하나는 컴퓨터의 리소스를 더 잘 활용할 수 있기 때문이다. 예를 들어, 한 스레드가 네트워크를 통해 전송된 요청에 대한 응답을 기다리는 경우 다른 스레드가 그동안 CPU를 사용하여 다른 작업을 수행할 수 있다.
또한 컴퓨터에 여러개의 CPU가 있거나 CPU에 여러개의 실행 코어가 있는 경우 멀티스레딩을 통해 응용 프로그램에서 이러한 추가 CPU 코어를 활용할 수 있다.
Better Utilization of Multiple CPUs or CPU Cores
컴퓨터에 여러개의 CPU가 있거나 CPU에 여러개의 실행 코어가 있는 경우 모든 CPU 또는 CPU 코어를 활용하려면 응용 프로그램에 여러개의 스레드를 사용해야 한다.
Better User Experience with Regards to Responsiveness
멀티 스레딩을 사용하는 또 다른 이유는 더 나은 사용자 경험을 제공하기 위한 것이다. 예를 들어 GUI에서 버튼을 클릭하여 네트워크를 통해 요청이 전송되면 이 요청을 수행하는 스레드는 GUI 응답 결과를 받는 동안 다른 작업을 할 수 없게 된다. 대신 이러한 요청은 백그라운드 스레드에 의해 수행될 수 있으며 그동안 GUI 스레드는 다른 사용자 요청에 자유롭게 응답할 수 있다.
Better User Experience with Regards to Fairness
네번째 이유는 사용자간에 컴퓨터 리소스를 보다 공정하게 공유하기 위한 것이다. 예를 들어 클라이언트로부터 요청을 수신하고 이러한 요청을 실행할 스레드가 하나 뿐인 서버를 상상해보아라. 클라이언트가 처리하는데 시간이 오래 걸리는 요청을 보내면 다른 모든 요청은 해당 요청이 완료될 때까지 기다려야한다. 각 클라이언트의 요청을 자체 스레드로 실행하면 단일 작업으로 CPU를 독점할 수 없다.
Multithreading vs Multitasking
예전에는 컴퓨터에 단일 CPU가 있었고 한번에 하나의 프로그램만 실행할 수 있었다. 대부분의 작은 컴퓨터는 여러 프로그램을 동시에 실행할 수 있을만큼 강력하지 않았기 때문에 시도조차 하지 않았다.
멀티 태스킹 | 멀티 스레딩 | |
기능 | OS의 기능 | 프로세스의 기능 |
실행 | 여러 프로세스가 동시에 실행 | 단일 프로세스에서 여러 스레드의 실행 |
자원 | 프로세스 간에 리소스를 공유 | 스레드 간에 리소스를 공유 |
예를 들어, Linux는 멀티 태스킹 OS이다. 예를 들어, 일부 프로세스가 동시에 실행되는 것을 볼 수 있다. 예를 들어, 이 Java 프로세스가 동시에 내 컴퓨터에서 실행된다.
Multitasking
나중에 멀티 태스킹이 발생하여 컴퓨터가 동시에 여러 프로그램(작업 or 프로세스)을 실행할 수 있게 되었다. 그래도 실제로 '동시'는 아니었다. 단일 CPU 자원은 여러 프로그램 간에 공유 되었다. 즉 운영 체제는 여러 프로그램들을 돌아가면서 잠시동안 실행시키는 작업을 반복하며 프로그램을 작동 시킨다.( EX. A프로세스 실행 -> CPU 반환 -> B프로세스 실행 -> CPU 반환 -> A프로세스 실행 ) 멀티 태스킹과 함께 소프트웨어 개발자에게는 새로운 과제가 대두되었다. 그것은 프로그램이 더이상 사용 가능한 모든 CPU나 메모리 또는 기타 컴퓨터 리소스를 가지고 있다고 가정할 수 없다는 것이고, 이는 곧 좋은 프로그램은 더이상 사용하지 않는 모든 리소스를 해제하여 다른 프로그램에서 남는 리소스를 사용할 수 있도록 하는 프로그램이라는 것이다.
Multithreading
나중에 멀티 스레딩이 나오면서 동일한 프로그램 내에서 여러 스레드를 실행할 수 있게 되었다. 실행 스레드는 프로그램을 실행하는 CPU로 생각할 수 있다. 동일한 프로그램을 실행하는 여러 스레드가 있는 경우 동일한 프로그램 내에서 여러 CPU를 실행하는 것과 같다.
Multithreading is Hard
멀티 스레딩은 일부 유형의 프로그램 성능을 향상 시키는 좋은 방법이다. 하지만 멀티 스레딩이 멀티 태스킹보다 더욱 어렵다. 스레드는 동일한 프로그램 내에서 실행되므로 동일한 메모리를 동시에 읽고 쓴다. 두 개의 스레드가 실제로 '동시'에 실행되지 않기 때문에 이러한 오류 중 일부는 단일 CPU 시스템에서 보이지 않을 수 있다. 그러나 최신 컴퓨터에는 멀티 코어 CPU와 여러 CPU가 함께 제공된다. 이는 별도의 코어 또는 CPU가 동시에 별도의 스레드를 실행할 수 있음을 의미한다.
스레드가 메모리 위치를 읽는 동안 다른 스레드가 쓰면 첫 번째 스레드는 어떤 값을 읽는가? 오래된 값? 두 번째 스레드가 새로 쓴 값? 아니면 둘 사이의 값인가? 또는 두 개의 스레드가 동일한 메모리 위치에 동시에 쓰는 중이면 완료시 어떤 값이 남아있나? 첫 번째 스레드가 쓴 값? 두 번째 스레드가 쓴 값? 아니면 둘 사이의 값인가? 적절한 예방 조치 없이는 이러한 행동의 결과는 예측할 수 없을 것이다. 결과는 때때로 바뀔 것이다. 따라서 개발자가 올바른 예방 조치를 취하는 방법을 아는 것이 중요하다. 즉, 스레드가 메모리, 파일, DB 등과 같은 공유 자원에 접근하는 방법을 제어하는 학습을 의미한다. 이는 Java Concurrency tutorial이 다루는 주제 중 하나이다.
Multithreading and Concurrency in Java
Java는 개발자가 멀티 스레딩을 쉽게 사용할 수 있도록 하는 최초의 언어 중 하나였다. Java는 처음부터 멀티 스레딩 기능을 가지고 있었다. 따라서 Java 개발자는 종종 위에서 설명한 문제에 직면했다. 이것이 Java 동시성에 대한 tutorial을 작성하는 이유이다. ( 나를 비롯한 다른 Java 개발자에게 도움이 될만한 메모를 남기기 위함 )
주로 Java의 멀티 스레딩에 관한 것이지만 멀티 스레딩에서 발생하는 일부 문제는 멀티 태스킹 및 분산 시스템에서 발생하는 문제와 유사하므로 Concurrency가 적용되는 다른 곳에서도 참조할 수 있을 것이다. 따라서 'Multithreading'이 아니라 'Concurrency'라는 단어가 사용된다.
Concurrency Models
첫 번째 Java 동시성 모델은 응용 프로그램 내에서 실행되는 여러 스레드가 객체를 공유한다고 가정했다. 이 유형의 동시성 모델을 일반적으로 '공유 상태 동시성 모델' 이라고 한다. 많은 동시성 언어 구문과 유틸리티는 이 동시성 모델을 지원하도록 설계되었다.
그러나 최초의 Java 동시성 책이 작성된 이후와 Java5 동시성 유틸리티가 배포된 이후에도 동시 아키텍쳐 및 디자인 분야에서 많은 일이 발생했다.
공유된 상태 동시성 모델은 많은 동시성 문제를 유발하여 우아하게 해결하기가 어려웠다. 따라서 '공유 없음' 또는 '분리된 상태'라고 하는 대체 동시성 모델이 인기를 얻었다. 별도의 상태 동시성 모델에서 스레드는 객체나 데이터를 공유하지 않는다. 이것은 공유 상태 동시성 모델의 많은 액세스 문제를 피한다.
새로운 비동기 '별도의 상태' 플랫폼 및 Netty, Vert.x 및 Play/Akka 및 Qbit이 등장했다. 새로운 비차단 동시성 알고리즘이 게시되었으며 LMax Disrupter와 같은 새로운 비차단 도구가 툴킷에 추가되었다. Java7의 Fork and Join 프레임 워크와 Java8의 콜렉션 스트림 API에 새로운 기능적 프로그래밍 병렬처리가 도입되었다.
Java Concurrency Study Guide
Java 동시성을 처음 접하는 경우 아래 공부 계획을 따르는 것이 좋다.
일반적인 Concurrency 및 Multithreading 이론
- Multithreading Benefits
- Multithreading Costs
- Concurrency Models
- Same-threading
- Concurrency vs Parallelism
Java Concurrency의 기본
- Creating and Starting Java Threads
- Race Conditions and Critical Sections
- Thread Safety and Shared Resources
- Thread Safety and Immutability
- Java Memory Model
- Java Synchronized Blocks
- Java Volatile Keyword
- Java ThreadLocal
- Java Thread Signaling
Java Concurrency의 전형적인 문제
- Deadlock
- Deadlock Prevention
- Starvation and Fairness
- Nested Monitor Lockout
- Slipped Conditions
위의 문제를 방지하는 Java Concurrency 구성
- Locks in Java
- Read / Write Locks in Java
- Reetrance Lockout
- Semaphores
- Blocking Queues
- Thread Pools
- Compare and Swap
추가 주제
- Anatomy of a Synchronizer
- Non-blocking Algorithms
- Amdahl's Law
- References
위 공부 계획에 대한 내용을 하나씩 정리해나갈 예정이다.
<원본 사이트 : http://tutorials.jenkov.com/java-concurrency/index.html#java-concurrency-study-guide>
'JAVA > Concurrency' 카테고리의 다른 글
# Java Concurrency In Practice - Chapter3 (0) | 2020.02.15 |
---|---|
# Java Concurrency In Practice - Chapter 2 (0) | 2020.02.13 |
# Java Concurrency In Practice - Chapter 1 (0) | 2020.02.03 |
# Java Concurrency and Multithreading Tutorial - Concurrency vs Parallelism (0) | 2020.01.31 |
# Java Concurrency and Multithreading Tutorial - Multithreading Benefits (0) | 2019.12.31 |