동시성 처리
물리적인 CPU 성능 향상이 한계에 다다르면서, 이제는 단순히 하드웨어를 업그레이드하는 방식만으로 시스템의 성능을 개선하기 어려운 시대에 접어들었다. 더 이상 ‘공짜 점심’은 존재하지 않는다. 과거에는 동일한 소프트웨어라도 더 빠른 CPU로 자연스레 성능 향상을 기대할 수 있었지만, 현대의 프로세서는 더 많은 일을 병렬로 처리할 수 있도록 다중 코어 구조로 진화하고 있다. 이러한 환경 변화는 개발자들에게 “동시성(Concurrency)”이라는 새로운 패러다임에 대한 이해와 대응을 요구한다.
본 글은 동시성 프로그래밍의 개념과 중요성을 설명하고, 객체지향 모델이 멀티쓰레드 환경에서 가지는 한계를 짚으며, 안전한 병렬 처리를 위한 설계 원칙들을 다룬다. 특히, 멀티코어 시대에 확장 가능한(Scalable) 시스템을 구축하기 위해 어떤 프로그래밍 모델과 구조가 필요한지 살펴보고, 자원을 효율적으로 활용하면서도 오류 없이 동작하는 코드를 작성하기 위한 실질적인 방향을 제시한다.
공짜 점심은 끝났다.
- 소프트웨어는 동일한데 CPU가 빨라지면 덩달아 빨라지는것
- Scale Up
성능 향상 특이점 이후의 CPU
- CPU는 더 이상 빨라지지 않고 더 많은 일(다중 코어)을 동시에 할 수 있게 발전 (-> Scale Out)
동시성을 고려한 프로그램을 작성해야 한다.
확장성 (Scalability)
- 하나의 시스템이 성능 향상에 지장을 받지 않고 자원에 대한 수요읠 변화를 수용할 수 있는 정도
- 수요의 증가를 수용할 때 자원을 추가 투입하는 것은 당연하고 단지 그 비율이 선형적이거나 아니면 조금 더 효율적이길 바란다.
동시성 (Concurrency)
- 확장성을 위한 수단으로써, 하마디로 자원을 더 주면 프로그램이 알아서 잘 활용하는 것
- 자원을 잘 활용하기 위한 프로그램의 복잡도가 증가하지 않거나 완만하게 증가하기를 바란다.
객체지향 모델링
- 객체란 은닉한 상태에 대해 지켜야 하는 논리를 보호하는 안전한 동작들만 노출 시킴
- 시스템은 메서드 호출에 반응하여 내부의 상태를 수정하는, 즉 전체 상태를 진전시키는 동작 호출을 통해 서로와 통신하는 객체 인스턴스의 네트워크로 표현
멀티쓰레드
- 객체에서의 은닉이라는 것은 멀티쓰레드 환경을 고려하지 않았다면 이러한 동작들이 안전하지 않게 되며 내부 상태 오염에 이르게 됨
- 실제 멀티 쓰레드 환경에서의 시스템은 쓰레드들이 동작 호출을 통해 객체 인스턴스의 네트워크를 따라 이동하는 것
객체지향 모델링의 한계
- 상태의 은닉만으로는 동시에 동작을 호출하는 것에 대한 보호를 할 수 없음
- getNext()는 세가지 동작으로 구성
- value -> 9
- 9 + 1 -> 10
- 10 -> value
- value -> 10
- 10 + 1 -> 11
- 11 -> value
1 | public class UnsafeSequence { |
- 쓰레드를 제어해야 함
쓰레드
- 프로세스란 격리되어 있고 독립적으로 동작하는 OS의 관리 단위로 순차적인 실행과 OS의 I/O를 통한 외부와의 통신을 특징으로 함
- 쓰레드는 프로세스내에서 동시적인 실행과 메모리 공유를 통한 통신
- 처리량의 향상
- 메모리 공유라는 것은 비순차성을 의미하며 개발이 복잡해지고 추론이 어려워지는 것을 의미
- 충분히 동기화하지 않으면 멀티쓰레드에서의 동작들의 순서는 예측 불가
- 멀티쓰레드라는 것이 전체 성능은 올릴지라도 어느 정도의 런타임 부하를 수반
동시적 프로그래밍
- 공유하고 변경 가능한 상태에 대한 접근을 통제
- 멀티 쓰레드에 안전한 코드를 만든다는 것은
- 상태를 쓰레드간에 공유하지 않는다.
- 상태를 변경 불가능하게 한다.
- 상태를 접근할 때 동기화를 사용한다
- 하나 이상의 쓰레드가 상태에 접근하고 그 중 하나가 변경할 수 있다면 이 모든 쓰레드들은 동기화를 통해 해당 상태에 대한 접근을 순서대로 배열하여야 한다.
1 | public class StatelessFactorizer implements Servlet { |
소인수분해를 하는 서블릿
- 상태가 없으면 통제할 대상이 없으므로 항상 멀티쓰레드에 안전
1 | import java.math.BigInteger; |
WIP…
You need to set
install_url
to use ShareThis. Please set it in _config.yml
.