Whiteship's Note


Shared Mutable State

Spring DM/OSGi : 2008.09.25 11:33


공유하는 불변 객체

가능한한 최소한의 객체만 공유하고, 가능한한 공유하는 객체를 immutable하게 유지함으로써, 기본적으로 "동시성 문제" 크기를 줄인다. 불행히도 이 방법으로는 문제 크기를 0으로 만들지는 못한다. 실제 대부분의 애플리케이션에서 공유하는 불변 객체 사용을 완전히 없애진 못하기 때문에, 그럴 때 안전한 방법을 찾아야 한다.

서비스 기반 코드 예제를 살펴보자. 등록된 메일 박스 서비스의 Map을 관리한다고 가정해보자. 이름을 키로 사용하고 getMailboxByName 이라는 public 메소드를 제공하여 특정 메일 박스 또는 대응하는 박스가 없으면 null을 반환하도록 한다. 이 예제 코드는 6.1에서처럼 자바 synchronized 블럭을 사용하여 쓰레드 세이프티를 보장한다. 이 클래스는 잘 동작한다. 동일한 객체에 접근할 땐 해당 객체의 롹을 지니고 접근해야 하기 때문이다. 비록 맵 필드 자체는 final 이지만, map이 가지고 있는 내용물은 mutabl하며 여러 쓰레드가 공유하고 있다. 따라서 lock으로 보호해야 한다. 또란, 동기화 블럭은 가능한한 짧고, 빨리 롹을 반환해야 한다.

=> 음.. 글쿤 mutale한 객체를 공유하는 경우가 어떤건지 감이 오는군. 역시 예제가 있어야 이해하기 쉽네.

하지만, 코드 6.1은 Java 5에 도입된 새로운 동시성 기능의 장점은 하나도 이용하고 있지 않다. 자바 5의 기능을 사용하면 동시에 여러 쓰레드가 getMailboxByName 메소드를 호출하는 것이 가능하다. 이전 동기화 블럭은 읽기와 쓰기를 구분할 수 없었다. 모든 메소드 접근시에 불필요하게 롹 객체를 요구했다. 하지만 Java 4에 도입된 Read/Write 롹은 이를 구분할 수 있게 해준다. 코드 6.2는 이 기능을 사용하여 여러 쓰레드가 동시에 맵에서 읽기 작업을 할 수 있게 해준다. 물론 동시에 변경은 못하게 막고 있다.

만약 자바 5를 사용할 수 있는 환경이라면, 그 안에 들어있는 새로운 concurrnt 라이브러리를 확인해보는게 좋겠다. 자바 1.4를 사용하고 있다면 동기화 블럭 사용을 주저하지 말아라. 많은 개발자들은 성능 문제로 동기화 블럭 사용을 주저하지만, 실제로 동기화 블럭을 최대한 작게 유지만 한다면 그렇게 성능이 나쁘진 않다.  그리고 무엇보다 성능 조금 높이자고 동기화 문제를 방치한다는 건 말이 안 된다.

=> 옳커니~. 자바 5에 그런 게 있었구나.. 우와;; 평소에 쓰레드 다룰 일이 거의 없으니 완전 몰랐네.

=> 살펴 볼 클래스
- ReadWriterLock
- ReentrantReadWriteLock



'Spring DM > OSGi' 카테고리의 다른 글

OSGi 툴 세트 Pax  (0) 2008.10.21
Shared Mutable State  (2) 2008.09.25
The Price of Freedom  (0) 2008.09.25
Concurrency and OSGi  (0) 2008.09.25
BundleContext로 할 수 있는 일  (0) 2008.06.25
2 Security Layer  (0) 2008.02.18
1. Introduction  (0) 2008.02.17
top


The Price of Freedom

Spring DM/OSGi : 2008.09.25 11:13


참조 : http://neilbartlett.name/blog/osgibook/

자유의 댓가.

=> 쓰레드를 맘대로 만들어 사용할 수 있는 자유의 댓가.

상상으로 만든 A, B, C 번들에 대한 간다한 시나리오를 살펴보자. 그림 6.1에 UML 시퀀스 다이어그램으로 나타냈다. 번들 A가 쓰레드를 시작시키고 어느 순간 번들 B에 접근하여 해당 쓰레드에서 번들 B의 start 메소드를 호출한다. 그러면 번들 B가 활동을 시작하고(active), 번들 B 액티베이터의 start 메소드가 번들 A가 만든 쓰레드에서 호출될 것이다. 게다가, B의 start 메소드에서 어떤 서비스를 등록하고, C가 서비스 트래커로 이 서비스 타입을 리스닝하고 있다. 번들 C 트래커의 addingService 메소드가 호출되고, 이 역시 A가 만든 쓰레드에서 호출된다. 마지막으로 C가 B가 등록한 서비스를 주기적으로 호출하는 쓰레드를 만들었다고 가정해보자.

=> 아.. 너무해. 이게 뭔리야. 좀 차근 차근 얘기해주지. -_-;; 그러니까...
1. 번들 A가 쓰레드를 만들고 거기서 번들 B의 start 메소드를 호출해서 번들 B를 활성화 시킨다.
2. 번들 B의 start 메소드에서는 번들 C가 리스닝하고 있는 서비스를 서비스 레지스트리에 등록한다.
3. 번들 C는 새로운 쓰레드를 만들어서 주기적으로 B가 등록한 서비스를 가져온다.
이말인가? 그렇다 치고..

사용자 삽입 이미지

클라이언트가 서비스 레지스트리에서 서비스를 가져갈 때, 프록시나 랩퍼가 아닌 진짜 서비스 객체를 찾는다. 따라서 클라이언트가 서비스에 메소드를 호출할 때, 해당 호출들은 기본적으로 동기적인 메소드 호출이다. 즉, 쓰레드에서 실행하는 서비스 메소드를 클라이언트 번들이 "쥐고있다."(owned)라는 뜻이다.

=> 넹.

또한, 많은(전부는 아님) OSGi 내의 알림은 동기적으로 발생한다. 프레임워크가 콜백을 사용하는 메소드(ServiceEvent를 등록되엉 있는 서비스 리스너로 보내는 것이나 번들 엑티베이터의 start 또는 stop 메소드를 호출하는 것 같은)에 의해 호출될 때, 그런 콜백들은 동일한 쓰레드에서 실행되고, 이전 제어권이 프레임워크 메소드를 호출한 쪽에 되돌아가기 전에 완료해야 한다.

=> 아.. 어렵다. 프레임워크의 어떤 메소드에 콜백을 넘겨줬을 때, 그 콜백도 같은 쓰레드에서 호출된다는 것이고, 해당 콜백 실행이 완료한 다음에, 제어권을 넘겨줘야 한다는 것이군.

위와 같은 상황에는 세 개의 주요 가정이 존재한다.
  • 콜백과 서비스 메소드는 어떤 쓰레드에서든 호출될 수 있다. 여러 쓰레드에서 동시에 호출될 수도 있을 것이다. 이를 주시하지 않고 코딩했을 때는 예상하지 못한 문제를 발생시킬 수 있다.
  • 우리가 작성할 콜백과 서비스 메소드를 호출하는 쓰레드는 우리가 만들 것에 "포함되어 있지 않다." 만약 오랜 시간 동작하거나, blocking I/O를 이런 콜백에서 사용한다면 전체 시스템을 지연시킬 수 있다.
  • OSGi API 메소드를 사용하면, 우린 해당 프레임워크가 어떤 리스너나 콜백을 사용하는지 예측할 수 없고, 따라서 해당 콜백에서 어떤 롹을 취하려는지도 알 수가 없다. 만약 그런 메소드를 호출하는 도중 다른 롹을 가지고 있다면, daedlock을 발생키질 위험이 있다.
이런 문제에 대한 해결책은 좋은 동시성 프로그래밍 프랙티스를 사용하는 것이다. 하지만, 안전한 동시성은 그렇게 어렵지 않다. 최소한 블라 블라 하는 것처럼. 천재만 할 수 있는 것이 아니다. 핵심은 (많은 천재들이 하지않는) 훈련이다. 몇 가지 규칙을 적용하여, 우리가 맞닥들이게 될 대부분의 상황을 쉽게 처리할 수 있다.

1. 변하는(Immutable) 객체는 자동적으로 쓰레드 세이프하며, 여러 쓰레드에 걸쳐 공유될 객체가 아니라면 쓰레드 세이프 해야할 이유가 없다. 따라서 가능한 공유할 것을 최소화 하고 가능한 immutable 객체를 사용하라.

2. 공유하는 불변의(mutabl) 객체가 정말로 꼭 필요한 경우, 모든 접근(읽기 쓰기)을 막아서 동일한 객체의 롹을 가지고 필드를 보호하거나 volatile 변수를 사용하라.

3. 이미 롹을 가지고 있는 상태에서 새로운 롹을 얻으려고 하지 말아라. 이 규칙을 따르면 자연스래, 롹을 얻으려는 시도를 할지도 모르는 "아는바없는" 혹은 "외부" 코드를 호출할 때는 어떤 롹도 쥐고 있어서는 안 된다. 이는 서비스 또는 OSGi API를 호출할 때를 말하며, 이들 중 대부분이 다른 번들의 콜백을 우리가 만든 쓰레드에서 실행하게 된다.

=> 글쿤, 롹을 쥐고 있는 상태에서 롹을 가지려고 할지도 모르는 어떤 서비스 또는 OSGi API를 호출하면 deadlock이 발생할 수 있으니, 그럴 땐 롹을 쥐고 있지 말라는 것이로군요.

=> 한가지 궁금한건 2번에서 volatile을 사용하면 모든 쓰레드에서 동일한 값을 사용하게 될텐데 그렇게 되면, 결국엔 mutable 하지 못한게 된느거 아닌가.. 흠.. A 쓰레드에서 foo.name을 a라고 하고 B 쓰레드에서 foo.name을 찍으면 a가 찍힐테고 B 쓰레드에서 다시 foo.name을 b라고 하면, 이번엔 A 쓰레드에서 foo.name을 찍으면 b가 찍힐텐데... 내가 volatile을 잘못이해한건가.. 아닌데, 맞을텐데, 아니면, mutable->immutable하게 사용하라는 것인가.. 차리리 ThreadLocal을 사용하는게 낫지 않을까. 아닌데 저자가 그걸 모를리도 없고, 아. mutable이니까, setter를 막아둬서 값 변경을 막아뒀겠구나.. 위와 같은 내 생각은 immutable객체를 공유할 때 생기는 문제지;. (흠.. 이것도 아닌가 위에선 분명 '읽기와 쓰기'라고 '쓰기'를 언급하고 있자나..) 흠..그럼 뮤터블 객체를 왜 공유해서 쓰는거지. 그럴 때 그 객체 값을 변경하지 못하면, 멀티 쓰레드 걱정 안해도 되는거 아니야? 아.. 다음 챕터를 읽어보자. 아 내 머리.

'Spring DM > OSGi' 카테고리의 다른 글

OSGi 툴 세트 Pax  (0) 2008.10.21
Shared Mutable State  (2) 2008.09.25
The Price of Freedom  (0) 2008.09.25
Concurrency and OSGi  (0) 2008.09.25
BundleContext로 할 수 있는 일  (0) 2008.06.25
2 Security Layer  (0) 2008.02.18
1. Introduction  (0) 2008.02.17
top


Concurrency and OSGi

Spring DM/OSGi : 2008.09.25 10:25


참조 : http://neilbartlett.name/blog/osgibook/

J2EE 같은 무거운(heavyweight) 프레임워크에 비해, OSGi는 쓰레드를 포함한 JVM의 모든 리소스를 제어하려 들지 않는다. J2EE에선 직접 쓰레드를 만들거나 명시적인 동기화(synchronization)를 하는 코드를 작성하는 것을 금하고, 대신에 제한적인 "작업 관리" 프레임워크를 제공한다. OSGi는 여러분이 직접 애플리케이션에서 쓰레드를 만들고 스케쥴링을 할 수 있다. 그렇게 하려면 OSGi 라이브러리들은 쓰레드 세이프해야 하며 어떤 쓰레드에서도 호출할 수 있어야 한다.

=> 즉, OSGi에서는 쓰레드를 직접 다루는 코드를 작성할 수도 있으니, 쓰레드 세이프한 라이브러리를 만드는 것이 중요하다는 뜻인듯..

하지만, 이런 자유에는 댓가가 따르듯이, 우리가 만들 번들에서 쓰레드를 생성하여 사용하는것이 가능하듯이, 우리가 만들 번들이 단일 쓰레드 환경에서만 사용되리라는 보장은 못한다. OSGi는 암묵적으로 멀티 쓰레드다. 따라서 반드시 작성하는 코드가 쓰레드 세이프해야 하며, 특히 이벤트나 콜백을 다른 프레임워크 또는 번들에서 받아올 때 주의해야 한다.

=> 흠. 당연한 말씀.

Brian Goetz의 "Java Concurrency in Practice"에서 자바 동시성에 대해 자세히 다루고 있으니, 프로페셔널 자바 프로그래머라면 항상 이 책을 가까이 하라.

=> 넵.

'Spring DM > OSGi' 카테고리의 다른 글

OSGi 툴 세트 Pax  (0) 2008.10.21
Shared Mutable State  (2) 2008.09.25
The Price of Freedom  (0) 2008.09.25
Concurrency and OSGi  (0) 2008.09.25
BundleContext로 할 수 있는 일  (0) 2008.06.25
2 Security Layer  (0) 2008.02.18
1. Introduction  (0) 2008.02.17
top


Java Concurrency In Practice 번역서 등장

모하니?/Reading : 2008.07.18 17:52


와우~~ 미투데이 하다가 알게 되었습니다. OSGi를 잘 알고 잘 사용하려면 최소한 클래스로딩과 컨커런시를 잘 이해하고 사용할 수 있어야 되는데, 저 책이 좋다고 자바 개발자라면 저 책을 꼭 끼고 있으라는 글을 어느 영문 아티클에선가, 블로그 글이었던가, 댓글에선가 본적이 있는데, 안 그래도 어려운 내용이 영어라서 학습하기 부담스러웠는데, 정말 잘 됐습니다. 번역도 기대 만큼 잘 되어있기를 바라면서 출간을 기다려 봅니다.

사용자 삽입 이미지


'모하니? > Reading' 카테고리의 다른 글

[거꾸로 읽는 세계사] 드레퓌스 사건을 보고서...  (0) 2010.03.10
TDDBE 2부 xUnit 실습  (0) 2008.09.08
도와주세요! 팀장이 됐어요  (0) 2008.08.25
내가 시집을 읽게 될 줄이야...  (4) 2008.08.05
불신자를 위한 JSF 시리즈  (0) 2008.07.22
Java Concurrency In Practice 번역서 등장  (0) 2008.07.18
이외수의 생존법 하악하악  (0) 2008.04.07
책 지름신 오셨네~  (0) 2007.12.26
Head First SQL  (4) 2007.12.21
읽을 책 정리  (2) 2007.12.21
괴짜경제학  (4) 2007.12.10
top