독서일지/클린 코드

클린 코드 독서일지 - Day 45

Sadie Kim 2023. 12. 24. 01:39

라이브러리를 이해하라

Executor 프레임워크

애플리케이션에서 스레드를 사용할 때 Executor 클래스를 고려하면 좋다.

  • Executor 프레임워크는 스레드 풀을 관리하고 풀 크기를 자동으로 조정하며 필요하다면 스레드를 재사용함.
  • Future도 지원 -> 독립적인 연산 여럿을 실행한 후 모두가 끝나는 것을 기다릴 때 유용

스레드를 차단하지 않는 방법(논 블로킹)

최신 프로세서는 차단하지 않고도 안정적으로 값을 갱신함 => 흔히 CAS라 불리는 연산 덕분(데이터베이스 분야에서 낙관적 잠금이라는 개념과 유사)

synchronized 키워드가 언제나 락을 거는 것과 다르게, CAS 연산은 스레드가 같은 값을 수정해 문제를 일으킬 때를 감지하여 이럴 경우에만 갱신이 성공할 때까지 재차 시도함 ⇒ 락을 거는 쪽보다 문제를 감지하는 쪽이 거의 항상 더 효율적이다.

다중 스레드 환경에서 안전하지 않은 클래스

본질적으로 다중 스레드 환경에서 안전하지 않은 클래스가 있음 :

  • SimpleDateFormat
  • 데이터베이스 연결
  • java.util 컨테이너 클래스
  • 서블릿

몇몇 집합 클래스는 스레드에 안전한 메서드를 제공하지만 그런 메서드 여럿을 호출하는 작업은 스레드에 안전하지 않음

메서드 사이에 존재하는 의존성을 조심하라

스레드 하나가 코드를 실행한다면 아무 문제도 없지만, 스레드 두 개가 인스턴스 하나를 공유한다면 예외가 발생할 가능성이 작게나마 존재함

ex) 정수 목록의 끝을 정하고 연산하는 클래스에서, 정수 목록 끝에서 스레드가 서로 간섭할 때 문제가 발생하는 경우

해결방법은 세 가지다.

  1. 실패를 용인한다 : 실패해도 괜찮도록 프로그램을 조정하는 방법. 다소 조잡한 방법임
  2. 클라이언트-기반 잠금 : 각 클라이언트가 직접 락을 거는 방법. 서버를 사용하는 모든 프로그래머가 락을 기억해 객체에 걸었다 풀어야 하므로 다소 위험한 전략임
  3. 서버-기반 잠금 : 잠금 메커니즘을 서버에 구현하는 방법. 일반적으로 클라이언트-기반 잠금보다 바람직함
    • 코드 중복이 줄어듦
    • 성능이 좋아짐
    • 오류가 발생할 가능성이 줄어듦
    • 스레드 정책이 하나임
    • 공유 변수 범위가 줄어듦