[클린코드] Ch 13

Ericamoyed·2021년 2월 12일
0

클린코드

목록 보기
6/8

Chapter 13

동시성

스레드가 하나인 프로그램은 무엇과 언제가 서로 밀접

  • 무엇(What)과 언제(When)을 분리하면, 애플리케이션 구조와 효율이 극적으로 나아짐
  • ex) 서블릿 모델: EJB(Enterprize Java Bean) 컨테이너로 관리되는데, 이들은 동시성을 부분적으로 관리
  • 실제로 컨테이너가 어떻게 동작하는지, 어떻게 동시 수정, 데드락 등과 같은 문제를 피하고 있는지 알아야 함
  • 구조적 개선, 응답 시간과 작업 처리량 개선을 위해 동시성을 사용함

동시성 방어 원칙

  • 단일 책임 원칙 (Single Responsibility Principle)
    • 동시성 관련 코드는 다른 코드와 분리해야 함
  • 공유 객체를 사용하는 코드 내 critial section을 synchronized 키워드로 보호해야함
    • 하지만 해당 키워드를 너무 많이 사용하게 된다면 모든 임계영역이 올바로 보호됐는지 확인하느라 리소스 소비됨.. (DRY 위반)
      • DRY: Do not Repeat Yourself -> 반복하지 마라
  • 객체를 복사해서 읽기 전용으로 사용
  • 스레드는 가능한 독립적으로 구현: 각 스레드가 클라이언트 요청 하나를 처리하고, 모든 정보는 비공유 출처에서 가져오도록.
    • 하지만 대다수 애플리케이션은 결국 데이터베이스 연결과 같은 자원을 공유하는 상황에 처하지..
  • 스레드 환경에 안전한 컬렉션 사용하기
    • ReentrantLock, Semaphore, CountDownLatch, ...
  • 다중 스레드 애플리케이션 기본 term
    • Bounded Resource: ex) 데이터베이스 연결, 길이 일정한 읽기/쓰기
    • Mutual Exclusion: ex) 한 번에 한 스레드만 공유 자료/자원 사용 가능 (like DB write)
    • Starvation: 스레드가 영원히/오랫동안 자원을 기다림
    • DeadLock: 여러 스레드가 서로의 종료를 대기
    • LiveLock: 락을 거는 단계에서 서로가 서로를 방해
  • 생산자-소비자(Producer-Consumer)
    • 생산자 -> 대기열 -> 소비자
    • 대기열을 올바로 사용하고자 생산자/소비자 스레드는 서로에게 시그널
      • 두 스레드 모두 진행 가능한데도 불구하고 서로에게서 시그널을 기다리는 상황 발생 가능
  • 읽기-쓰기(Readers-Writers)
    • 쓰기 스레드의 버퍼 점유로 여러 읽기 쓰레드가 버퍼를 대기하다가 throuput 저하
  • 식사하는 철학자들(Dining Philosoper)

공유 객체 하나에는 메서드 하나만 사용하고 synchronized 키워드를 사용하는게 권장되지만, 그렇지 않은 경우 아래와 같이 해결한다.

  • 클라단: 클라이언트에서 첫번째 메소드 호출 전에 서버를 잠그고, 마지막 메서드 호출시까지 잠금 유지
  • 서버단: 서버에다가 서버를 잠그고 모든 메서드를 호출한 후 잠금을 해제하는 메서드를 구현
    • AOP로 ArcLock 등 구현 방식
  • synchronized 키워드의 남발은 결국 많은 락을 불러일으키고, 이는 스레드 지연 및 부하의 가중으로 이어지므로 critical section을 최대한 줄이자.
  • DeadLock
    • ex) Producer-Consumer 모델에서 Producer 스레드는 재빨리 종료했는데 Consumer 스레드가 Producer의 메시지를 영원히 기다리는 상황이 존재할 수 있음.

스레드 코드 테스트

  • 프로세서 수보다 많은 스레드를 돌려보자
  • 다중 스레드를 쓰는 코드 부분을 다양한 환경에 쉽게 끼워 넣을 수 있게 스레드 코드를 구현
  • 코드에 보조 코드를 넣어서 해당 코드에 접근할 수 있는 다양한 경로를 제안하여 실패를 일으키게 해본다.
    • ex) yield(), sleep(), ... 즉 jiggle 시킴

결론

  • 여러 스레드가 공유 자료를 조작하거나 자원 풀 공유 시 동시성 오류가 발생
  • 방지를 위해서 잠긴 영역에서 다른 잠긴 영역을 호출하지 않도록 한다
  • 스레드 코드는 많은 플랫폼에서 많은 설정으로 반복해서 계속 테스트 해야함
    • 매번 발생하는 문제가 아니기 때문
profile
꿈많은 개발자, 일상 기록을 곁들인

0개의 댓글