7 분 소요

지금까지 동시성 프로그래밍을 한 적은 많지 않다. 그 또한 이미 구현되어 있는 것들을 유지보수한 정도이기 때문에, 코드에 대해 깊게 고민한 적이 없었다. 지금 당장 이 챕터를 공부했다고 해서, 깨끗한 동시성 코드를 작성할 수 있을 것 같지는 않다. 그래도 다음에 동시성 코드를 작성해야할 상황이 온다면, ‘각별히’ 주의 해야한다는 사실을 기억하며 개발을 할 것이다.


📆TIL(Today I Learned) 날짜

2022.04.22

📑오늘 읽은 범위

13.동시성

✍🏻책에서 기억하고 싶은 내용

동시성과 깔끔한 코드는 양립하기 어렵다.

동시성이 필요한 이유?
동시성은 결합(coupling)을 없애는 전략이다. 즉, 무엇(what)과 언제(when)를 분리하는 전략이다. 스레드가 하나인 프로그램은 무엇과 언제가 서로 밀접하다.
무엇과 언제를 분리하면 애플리케이션 구조와 효율이 극적으로 나아진다. 구조적인 관점에서 프로그램은 거대한 루프 하나가 아니라 작은 협력 프로그램 여럿으로 보인다. 따라서 시스템을 이해하기가 쉽고 문제를 분리하기도 쉽다.

동시성과 관련된 타당한 생각

  • 동시성은 다소 부하를 유발한다. 성능 측면에서 부하가 걸리며, 코드도 더 짜야 한다.
  • 동시성은 복잡하다. 간단한 문제라도 동시성은 복잡하다.
  • 일반적으로 동시성 버그는 재현하기 어렵다. 그래서 진짜 결함으로 간주되지 않고 일회성 문제로 여겨 무시하기 쉽다.
  • 동시성을 구현하려면 흔히 근본적인 설계 전략을 재고해야 한다.

동시성 방어 원칙

  • 단일 책임 원칙(Single Responsibility Principle, SRP) : 동시성은 복잡성 하나만으로도 따로 분리할 이유가 충분하다.
    👉🏻따름 정리(corollary) - 자료 범위를 제한하라. 자료를 캡슐화하라. 공유 자료를 최대한 줄여라.
    👉🏻따름 정리 - 자료 사본을 이용하라. 공유 자료를 줄이려면 처음부터 공유하지 않는 방법이 제일 좋다.
    👉🏻따름 정리 - 스레드는 가능한 독립적으로 구현하라. 독자적인 스레드로, 가능하면 다른 프로세서에서, 돌려도 괜찮도록 자료를 독립적인 단위로 분할하라.

라이브러리를 이해하라
👉🏻언어가 제공하는 클래스를 검토하라. 자바에서는 java.util.concurrent, java.util.concurrent.atomic, java.util.concurrent.locks를 익혀라.

실행 모델을 이해하라

  • 생산자-소비자(Producer-Consumer) : 잘못하면 생산자 스레드와 소비자 스레드가 둘 다 진행 가능함에도 불구하고 동시에 서로에게 시그널을 기다릴 가능성이 존재한다.
  • 읽기-쓰기(Readers-Writers) : 읽기 스레드의 요구와 쓰기 스레드의 요구를 적절히 만족시켜 처리율도 적당히 높이고 기아(starvation)도 방지하는 해법이 필요하다.
  • 식사하는 철학자들(Dining Philosophers) : 기업 애플리케이션은 여러 프로세스가 자원을 얻으려 경쟁한다. 주의해서 설계하지 않으면 데드락, 라이브락, 처리율 저하, 효율성 저하 등을 겪는다.

동기화하는 메서드 사이에 존재하는 의존성을 이해하라
👉🏻공유 객체 하나에는 반드시 메서드 하나만 사용하라.

동기화하는 부분을 작게 만들어라
👉🏻동기화하는 부분을 최대한 작게 만들어라.

올바른 종료 코드는 구현하기 어렵다
👉🏻종료 코드를 개발 초기부터 고민하고 동작하게 초기부터 구현하라. 생각보다 오래 걸린다. 생각보다 어려우므로 이미 나온 알고리즘을 검토하라.

스레드 코드 테스트하기
👉🏻문제를 노출하는 테스트 케이스를 작성하라. 프로그램 설정과 시스템 설정과 부하를 바꿔가며 자주 돌려라. 테스트가 실패하면 원인을 추적하라. 다시 돌렸더니 통과하더라는 이유로 그냥 넘어가면 절대 안 된다.


❓궁금한 내용, 잘 이해되지 않는 내용

  • 없음

댓글남기기