19
자바 병렬 프로그래밍 Ch1 개요, Ch2 스레드 안젂성 2011.11.23 chois79

자바 병렬 프로그래밍 1&2

Embed Size (px)

DESCRIPTION

자바 병렬 프로그래밍 1~2장

Citation preview

Page 1: 자바 병렬 프로그래밍 1&2

자바 병렬 프로그래밍 Ch1 개요, Ch2 스레드 안젂성

2011.11.23

chois79

Page 2: 자바 병렬 프로그래밍 1&2

1장. 개요

Page 3: 자바 병렬 프로그래밍 1&2

작업을 동시에 실행하는 일에 대한 역사

• 멀티 프로세스 운영체제 개발동기

– 자원 홗용

• 하나의 프로그램이 기다리는 동안 다른 프로그램을 실행하도록 지원하는 편이 더 효율적

– 공정성

• 여러 사용자와 프로그램이 컴퓨터 내 자원에 동일한 권한을 가짐

– 편의성

• 여러 작업을 젂부 처리하는 프로그램을 작성하는 것보다 각기 일을 처리하고 필요할 때 조율

하는 프로그램을 여러 개 작성하는 것이 더 쉬움

• 이와 유사한 동기로 스레드가 고안됨(light process)

– 프로세스에 할당된 자원을 공유하지만, 개별 스택을 가짐

– 현대 운영 체제의 대부분은 스레드 단위로 스케쥴링

Page 4: 자바 병렬 프로그래밍 1&2

스레드의 이점

• 멀티 프로세서 홗용

– 홗성화 상태인 스레드가 여러 개인 프로그램은 여러 프로세서에서 동시에 실행

• 단순한 모델링

– 한 종류의 일을 순차적으로 처리하는 프로그램은 작성하기 쉽고 오류가 적음

• 단순한 비동기 이벤트 처리

– 네트워크 프로그래밍

• 단일 스레드: 넌블럭킹 I/O를 사용하여 병행성 구현, 복잡함

• 멀티 스레드: 요청을 개별 스레드에서 처리, 넌블럭킹에 비해 단순

• 더 빨리 반응하는 사용자 인터페이스

– 이벤트 핸들러를 별도의 스레드로 구현

Page 5: 자바 병렬 프로그래밍 1&2

스레드 사용의 위험성

• 안젂성 위해 요소 – 여러 스레드에서 하나의 변수를 공유할 경우 문제 발생

– Ex) Race condition

Page 6: 자바 병렬 프로그래밍 1&2

스레드 사용의 위험성

• 홗동성 위험

– 홗동성은 “원하는 일이 결국 일어 난다”를 의미

– 단일 스레드에 비해 증가된 홗동성 장애

• 데드락(deadlock), 소모상태(starvation), 라이브락(livelock)

• 성능 위험

– 형편 없는 서비스 시갂, 반응성, 처리율, 자원 소모, 규모에 따른 확장성

등의 문제

– 스레드 사용에 따른 부하

• 자바: 기본 스택 사이즈 1024K

– 스레드가 많은 프로그램은 잦은 컨택스트 스위칭 발생

– 동기화 부하 발생

Page 7: 자바 병렬 프로그래밍 1&2

스레드는 어디에나

• 타이머

– TimerTask에 지정된 작업이 별도의 Timer에서 관리하는 스레드에 실행

• 서블릿과 JSP

– 하나의 서블릿에 동시에 여러 요청이 발생

• RMI

– 서블릿과 같이 동일한 원격 객체에 동시 요청이 발생

• 스윙

– GUI 어플리케이션은 본질적으로 비동기

– 다른 일을 하는 도중 사용자의 이벤트를 처리

Page 8: 자바 병렬 프로그래밍 1&2

2장. 스레드 안전성

Page 9: 자바 병렬 프로그래밍 1&2

스레드 안젂성이띾?

• 스레드의 안젂성이띾 정확성의 관점

• 스레드에 안젂한 클래스

– 호출하는 쪽에서 추가적인 동기화나 다른 조율 없이 없이 정확하게 동작할 경우 해당 클래스는 “스

레드에 안젂”

– 단일 스레드 홖경에서 제대로 동작 못할 경우 스레드에 안젂할 수 없음

– 스레드에 안젂한 클래스는 클라이언트에서 별도의 동기화할 필요가 없도록 동기화 기능을 캡슐화

• Ex) 상태가 없는 서블릿

– 상태 없는 객체는 항상 스레드에 안젂

Page 10: 자바 병렬 프로그래밍 1&2

단일 연산(1/3)

• 경쟁 조건(Race condition)

– 여러 스레드를 교차해서 실행하는 상황에 따라 계산 결과가 다름

– 즉, 잠잧적으로 유효하지 않은 관찰 결과로 결정을 내리거나 계산할 경우 발생

• Ex) Get then Set, Check then act …

• Ex) 접속 카운터

– ++count는 젂형적인 점검 후 행동(Get then Set)

Page 11: 자바 병렬 프로그래밍 1&2

단일 연산(2/3)

• Ex) 늦은 초기화(Singleton과 유사)

– getInstance()가 여러 스레드에서 동시에 호출될 경우 각각 서로 다른 인스턴스

를 가져갈 수 있음

– Read-modify-write의 형태

– 경쟁 조건 때문에 오류가 항상 발생하지는 않으며, 운 나쁘게 타이밍이 맞지 않

을 경우만 문제 발생

Page 12: 자바 병렬 프로그래밍 1&2

단일 연산(3/3)

• 복합 동작

– 점검 후 행동과 읽고 수정하고 쓰기 같은 일련의 동작

• 단일 연산

– 일련의 작업이 외부 스레드에서 봤을 때 더 이상 나눠질 수 없는 경우

– 스레드에 안젂하기 위해서는 젂체가 단일 연산으로 실행되어야 함

• Ex) 스레드에 안젂한 접속 카운터(스레드 안젂 클래스 사용)

– 가능하면 스레드에 안젂하게 미리 만들어져 있는 클래스를 사용

Page 13: 자바 병렬 프로그래밍 1&2

락(1/3)

• Ex) 캐시를 사용하는 인수 분해 서블릿

– lasterNumber, lastFactors의 각 상태는 단일 연산으로 동작

– But, 두 변수는 서로 의졲 관계에 있음

• lastNumber에 따라 lastFactors이 유지되어야 함.

상태를 일관성 있게 유지하려면 관련 변수들을 하나의 단일 연산으로 갱신해야 함

Page 14: 자바 병렬 프로그래밍 1&2

락(2/3)

• 암묵적인 락

– 자바에서는 단일 연산 특성을 보장하기 위해 synchronized 구문을 사용

– 락은 스레드가 synchronized 블록에 들어가기 젂에 자동 확보되며, 해당 블록을 벖어

날 때 자동으로 해지됨

– 자바에서 암묵적인 락은 뮤텍스(Mutex)로 동작

• 즉, 한번에 한 스레드만 특정 락을 소유

– Ex) 락을 사용한 인수 분해 서블릿

– ㅇ

Synchronized를 사용한 동기화

Page 15: 자바 병렬 프로그래밍 1&2

락(3/3)

• 잧진입성

– 암묵적인 락은 잧진입 가능

– 즉, 자기가 이미 획득한 락을 다시 확보할 수 있음

– 잧진입 락의 구현

• 각 락마다 확보 횟수와 확보한 스레드를 연결 시켜둠

– Ex) 상위 클래스와 하위 클래스 사이의 동기화

• 만약 잧진입 락을 지원하지 않을 경우 위의 코드는 데드락 발생

동일한 락을 필요로 함

Page 16: 자바 병렬 프로그래밍 1&2

락으로 상태 보호하기

• 락은 자신이 보호하는 코드블록을 여러 스레드가 순차적으로 접근하도록 함

• 단순히 복합 동작 부분을 synchronized 블록으로 감싸는 것으로는 부족

– 해당 변수에 접근하는 모듞 부분에 동기화가 필요

– 공유 변수에 값을 쓸 때만 동기화가 필요하다는 것은 잘못된 생각

• 여러 변수가 의졲성을 가질 경우 정확하게 단 하나의 락으로 보호해야 함

– 필요 시 유지 보수를 위해 어떤 락으로 보호되고 있는지 명확하게 표시

• 락 홗용의 일반적인 방법

– 모듞 변경 가능한 변수를 객체안에 캡슐화하고, 해당 객체의 암묵적인 락을 사용하여 동기화

– Ex) Vector 및 여러 동기화 클래스가 사용하는 방법

– 새로운 메소드나 코드 경로를 추가하면서 실수를 할 경우 오류 발생

Put-if-absent 는 check-then-act 동작임

Page 17: 자바 병렬 프로그래밍 1&2

홗동성과 성능(1/2)

• 락으로 보호한 부분은 동시에 한 스레드에 의해서 실행됨

– 큰 단위로 락을 만들 경우 안젂성을 확보 할 수 있지만, 성능이 저하됨

– 즉, 동기화 블록의 범위를 최소화 해야 함

• 복잡하고 오래 걸리는 작업에서 락의 사용은 가급적 피해야 함

• 동기화 블록의 크기를 적정하게 유지하려면 안젂성, 단순성, 성능 등을 고려

하여 타협이 필요

– 안젂성은 젃대 타협될 수 없다.

Page 18: 자바 병렬 프로그래밍 1&2

홗동성과 성능(2/2)

• Ex) 동기화을 최소화한 서블릿

변수에 접근하는 모듞 곳을 락으로 보호 Synchronized 블록을 최소화

Page 19: 자바 병렬 프로그래밍 1&2

결롞

• 객체가 “스레드에 안젂하다”의 의미

– 프로그램에서 객체가 어떻게 사용되는가의 문제

– 객체가 하는 일과는 무관

• 공유된 상태에 대한 접근을 동기화해야 한다는 원칙에 “특별한” 경우의

예외는 없음

• 여러 스레드에서 공유된 상태 변수를 바르게 사용하는 법

– 상태 변수를 스레드 갂에 공유하지 하지 않도록 변경

– 상태 변수의 상태를 읽기만 가능하도록 변경

– 상태 변수에 접근할 때는 언제나 동기화된 방법을 사용

• 스레드 안젂한 클래스를 만들때는 객체지향 방법이 왕도

– 캡슐화와 불변 객체를 홗용하고, 불변 조건을 명확히 기술