조엘과 이외수

조엘 온 소프트웨어(예전에 나온 책)를 아직도 천천히 읽고 있습니다. 절대로 빨리 안 읽히는 책 중에 하나 입니다. 책의 중후반 부에 추상화에 대한 이야기가 나옵니다. 프로그래밍을 추상화 하는 도구가 개발되더라도 학습비용은 동일하다는 이야기를 해줍니다. 어차피 내부 구조를 이해하지 못하는 이상 아무리 좋은 도구로 쉽게 코드를 작성할 수 있다고 하더라도 어느 순간 에러에 막혀서 수 많은 시간을 소비할 수 있기 때문이라고 합니다. 굉장히 설득력이 있는 이야기 입니다.

잠자기 전에 가볍게 읽기 위한 책으로 이외수의 “글쓰기의 공중부양”을 보고 있습니다. 이 분의 책 초반부터 장난이 아닙니다. 단어를 채집하라고 하면서 머리끝부터 입까지 내려오면서 수많은 단어들을 나열해 두었습니다. 책을 10페이지도 읽기전에 지칠뻔 했습니다. 꾸역꾸역 참으면서 나아갔습니다. 그 다음에는 단어의 속성에 대한 이야기를 합니다. 그런다음에야 문장으로 넘어갑니다.

이외수님과 조엘이 만나면 얼마나 잘 통할까 하는 생각이 문득 떠올랐습니다. 글의 가장 세밀한 부분부터 시작해서 추상화 시키는 순으로 설명해주고 있는데 이 책을 조엘도 분명 좋아할 것 같습니다. 조엘이 한국인이었다면 말이죠.

쓰레드를 공부하는 학생과의 대화

쓰레드를 공부하고 있는 백기선 인스턴스 두 개의 대화를 공개합니다.

백기선 백기선1 = new 백기선();
백기선 백기선2 = new 백기선();

백기선1.ask(백기선2, “쓰레드는 왜이렇게 어렵죠?“);

사실 어려울 것이 없습니다. Thread 객체 하나 만들고, Runnable 인터페이스 구현한 클래스 하나 만들고, Thread.start() 해주면 끝납니다.

백기선1.ask(백기선2, “근데 왜이렇게 어려운 것처럼 느껴지죠?“);

자주 사용해보지 않았기 때문이며, 가장 큰 원인은 모든 책들에서 상당히 뒷부분에서 그것도 매우 어렵게 다루고 있습니다. 따라서 배우는 입장에서도 쓰레드가
뭐고 언제 어떻게 사용할 수 있는지 생각할 수 있는 시간이 주어진다기 보다 미리 겁을 주어먹고 도망가고 싶게 만들어 버립니다.
병행성 문제니 데드락이니 동기화 블럭이니 하는 어려운 단어들이 머리속을 휘저으면서 어서 빨리 도망가 버리라고 재촉을 하지요.
사실은 간단한데 말이죠.

백기선1.ask(백기선2, “진짜로 그렇게 간단한가요?“);

네.
간단합니다. 쓰레드가 여러개라고 해서 문제 될 것이 뭐가 있죠? 코딩하는 사람이 쓰레드 실행 순서를 관리하는 것도 아니고 그냥
start()만 해주고 정.. 필요하다면 잠깐 멈췄다가 깨워주는 정도의 일만 하면 되는 걸요. 그런 최소한의 비용으로 굉장히
재밌는 프로그램을 만들 수도 있습니다.
예를 들어, mp3 플레이어와 문서 편집기를 합친 애플리케이션을 만들 수도
있습니다. mp3 플레이어를 하나 만들고 실행 파일을 Runnable 인터페이스를 구현하도록 수정하고 내부 코드를 조금
수정(main에 있던 내용을 run 안으로 이동시켜야 겠죠.)하고 편집기 만든 다음에 역시 실행 파일을 Runnable
구현하도록 수정한 다음에 새로운 실행파일을 작성한 다음에 거기서 Thread 두 개 만든 다음에 위에서 Runnable을
구현하도록 수정한 것들을 생성자에 넣어주고 각각을 start() 시켜주면 됩니다.

백기선1.ask(백기선2, “진짜로 그렇게해도 아무 문제가 발생하지 않나요?“);

mp3 애플리케이션과 문서 편집기만 제대로 작성했다면 당연히 아무런 문제도 발생하지 않습니다. 왜냐면 두 쓰레드가 서로 공유하는 자원이 아무것도 없기 때문에 전~~~~~~~~혀 걱정할 것이 없습니다.

백기선1.ask(백기선2, “공유하는 자원이요?“);

네.
여러 쓰레드를 사용(멀티 쓰레드, Concurrent 프로그래밍)할 때 프로그래밍이 어려워 지는 이유는 딱 하나. 공유하는 자원
때문입니다. 여러 쓰레드가 하나의 자원에 접근할 때 여러 문제가 발생할 수 있는데 그것 때문에, 동기화(롹킹) 블럭이라는
대안책이 나온거고, 그 대인책이 또 다른 문제를 발생시킬 수도 있으며, 동기화라는 것 자체가 쉬운일이 아니기 때문에
Concurrent 프로그래밍이 어려운 것입니다. 이 모든 문제의 원인이 바로 여러 쓰레드들이 공유하는 자원이 있기 때문입니다.

백기선1.ask(백기선2, “여러 명이 공유하는 자원이라… 어떤 것이 있죠? 잘 안 와닿습니다.“);

가장 유명한 것으로 “데이터베이스”라는 것이 있습니다. 자료의 저장소로써 여러 명이 이 하나의 저장소 또는 여러 저장소에 있는
자료를 꺼내보거나 집어 넣거나 수정하는 일들을 통해서 여러가지 이익 창출을 하기도 합니다. 그놈의 데이터가 뭔지.. @_@
암튼. 딱 DB야 말로 여러 명이 공유하는 자원에 가장~ 적합한 예에 해당합니다.
워드 문서파일도 마찬가지죠. 하나의 파일을 두 개의 편집기에서 동시에 열고 작업한다고 생각해 보세요.

백기선1.ask(백기선2, “그럼 멀티 쓰레드가 하나의 자원에 접근할 때 발생하는 문제와도 관계가 있겠군요.”);

당연하죠. 그래서 DB에서 발생할 수 있는 Concurrency Problems을 살펴보시면 이 문제들이 자바 애플리케이션에서도 고대~로 나타날 수 있는 것들임을 직작할 수 있을 것입니다.

Concurrent Programming with J2SE 5.0

참조 : http://java.sun.com/developer/technicalArticles/J2SE/concurrency/

Concurrency problem을 검색하다가 발견한 링크 입니다. Java 5에 추가되었다던 기능들을 어느 정도 살펴봤다고 생각하고 있었지만, 착각이였습니다.

“뉴욕의 프로그래머”를 보면 Java 5 이전 버전에서 사용하던 synchronized 블럭, Object.wait(), and Object.notify() 들이 비효율적이기 때문에 어떤 교수가 만들어서 사용하고 있던 Concurrent API를 Java 5에 추가했다. 라는 내용이 있습니다.

바로 그 부분에 해당하는 내용을 간략하게 소개한 아티클로 2005년에 작성된 문서인데 Agile Java 스터디를 준비하다가 2007년 9월 막바지에 발견하게 되었습니다.

현재는 위의 내용을 정리하기 전에 Thread를 어떻게 사용하고, 사용할 때 어떤 문제들이 발생할 수 있는지 정리하고 있습니다. 그리고 그 문제들을 어떻게 방지할 수 있는지 정리한 다음에 위의 문서를 정리할 생각입니다.