요점정리/자바 병렬 프로그래밍 Java Concurrency in Practice

01. 개요 / 02. 스레드 안정성

dextto™ 2014. 8. 31. 20:46

제목: (멀티 코어를 100% 활용하는) 자바 병렬 프로그래밍 / Java Concurrency in Practice

저자: 브라이어 게츠, 더그 리, 팀 피얼스, 조셉 보우비어, 데이빗 홈즈, 조슈아 블로쉬

출판사: 에이콘


01. 개요

개요 부분은 스레드를 다룰 때 많은 책들에서 언급하는 동시성 문제와 성능 위험에 대해 이야고 있음.


02. 스레드 안정성

만약 여러 스레드가 변경할 수 있는 하나의 상태 변수를 적절한 동기화 없이 접근하면 그 프로그램은 잘못된 것이다. 이를 고치는 세가지 방법.

  • 해당 상태 변수를 스레드 간에 공유하지 않거나
  • 해당 상태 변수를 변경할 수 없도록 만들거나 (불변객체?)
  • 해당 상태 변수에 접근할 땐 언제나 동기화를 사용한다.


스레드 안전한 클래스를 설계할 땐, 바람직한 객체 지향 기법이 왕도다. 캡슐화와 불변 객체를 잘 활용하고, 불변 조건을 명확하게 기술해야 한다.


추상화와 캡슐화 기법이 성능과 배치된다면 성능을 개선하기 전에 코드를 올바르게 작성하는 것이 먼저다. 

최적화는 성능 측정을 해본 이후에 요구 사항에 미달될 때만 하는 편이 좋다.


스레드 안전한 클래스란?

여러 스레드가 클래스에 접근할 때, 실행 환경이 해당 스레드들의 실행을 어떻게 스케줄하든 어디에 끼워 넣든, 호출하는 쪽에서 추가작인 동기화나 다른 조율 없이도 정확하게 동작한다면 해당 클래스는 안전하다고 말한다.

스레드 안전한 클래스는 클라이언트 쪽에서 별도로 동기화할 필요가 없도록 동기화 기능도 캡슐화한다.


2.3 락(Lock)

암묵적인(intrinsic) 락(또는 모니터 락) : 메소드 선언부에 synchronized 키워드를 지정하는 락. 해당 클래스의 인스턴스를 락으로 사용한다.


재진입성(reentrant): 특정 스레드가 자기가 이미 획득한 락을 다시 확보하는 것. 암묵적인 락은 재진입 가능하다. JVM은 락에 대한 소유 스레드와 확보 횟수를 관리한다. 

재진입성이 없다면 다음의 경우 문제가 된다. 부모/자식 클래스 둘다 synchronized 선언된 doSomething이라는 메소드가 있다. 그런데 하위 클래스에서 super.doSomething을 호출할 때 데드락에 빠지게 된다.


2.4 락으로 상태 보호하기

여러 스레드에서 접근할 수 있고 변경 가능한 모든 변수를 대상으로 해당 변수에 접근할 때는 항상 동일한 락을 먼저 확보한 상태여야 한다. 이 경우 해당 변수는 확보된 락에 의해 보호된다고 말한다.

모든 변경할 수 있는 공유 변수는 정확하게 단 하나의 락으로 보호해야 한다. 유지 보수하는 사람이 알 수 있게 어느 락으로 보호하고 있는지를 명확하게 표시하라. 


2.5 활동성과 성능

종종 단순성과 성능이 서로 상충할 때가 있다. 동기화 정책을 구현할 때는 성능을 위해 조급하게 단순성(잠재적으로 안정성을 훼손하면서)을 희생하고픈 유혹을 버려야 한다.

복잡하고 오래 걸리는 계산 적업, 네트웍 작업, 사용자 입출력 작업과 같이 빨리 끝나지 않을 수 있는 작업을 하는 부분에서는 가능한 한 락을 잡지 말아라.







반응형