'작업을 동시에 한다.' 라는것, 여러가지 일을 동시에 처리하는 것. 

그러면서도 서로간에의 일에 대해 안정성을 보장해 줘야 하고, 제대로 된 결과를 도출하기 위해 데이터를 보호해야 한다.


한번에 한가지씩 처리할 때는 큰 문제가 없었지만, 컴퓨터는 계속 발전하고, 사람들도 똑똑해지고, 점점 효율성을 찾다 보니, 이제는 컴퓨터가 여러 일을 동시에 효율적으로 처리할 수 있게되었다.


여러 프로그램을 동시에 처리할 수 있는 운영체제를 개발하게 된 몇 가지 요인은 아래와  같다고...


 자원 활용: 프로그램은 때로 입출력과 같이 외부 동작이 끝나기를 기다려야 하는 경우가 많은데 기다리는 동안은 유용한 일을 처리하지 못한다. 따라서 하나의 프로그램이 기다리는 동안 다른 프로그램을 실행하도록 지원하는 편이 더 효율적이다.

 공정성: 여러 사용자와 프로그램이 컴퓨터 내 자원에 대해 동일한 권한을 가질 수 있따. 한 번에 프로그램 하나를 끝까지 실행해 종료된 이후에야 다른 프로그램을 시작하는 것보다는 더 작은 단위로 컴퓨터를 공유하는 방법이 바람직 하다.


 편의성: 때론 여러 작업을 전부 처리하는 프로그램 하나를 작성하는 것보다 각기 일을 하나씩 처리하고 필요할 때 프로그램 간에 조율하는 프로그램을 여러 개 작성하는 편이 더 쉽고 바람직하다.




동시에 여러 일을 처리한다고 하지만, 컴퓨터가 처리하는건 어디까지나 순차적인 일련의 명령들의 반복일 뿐이다. 이런 과정을 좀 더 세분화 하고, 좀 더 세분화 한다. 여기에 자원 활용, 공정성, 편의성등의 요인들이 더해져, 스레드가 고안됐다.(프로세스 개념을 만들어 내게 된 것 처럼.)

그래서 스레드를 가벼운 프로세스(lightweight process)라고 부르기도 한다. 현대 운영체제 대부분은 프로세스가 아니라 스레드를 기본 단위로 CPU 자원의 스케줄을 정한다. 스레드는 메모리, 파일 핸들과 같이 프로세스에 할당된 자원을 공유한다. 각 스레드는 별도의 프로그램 카운터, 스택, 지역 변수를 갖는다. 또한 프로그램을 스레드로 분리하면 멀티프로세서 시스템에서 자연스럽게 하드웨어 병렬성을 이용할 수 있따. 즉, 한 프로그램 내 여러 스레드를 동시에 여러개의 CPU에 할당해 실행시킬 수 있다.


스레드는 자신이 포함된 프로세스의 메모리 주소 공간을 공유하기때문에, 한 프로세스 내 모든 스레드는 같은 변수에 접근하고 같은 힙 영역에 객체를 할당한다. 이는 프로세스 때보다 더 세밀한 단위로 데이터를 공유할 수 있게 한다. 

하지만 공유된 데이터에 접근하는 과정을 적절하게 동기화 하지 않으면 다른 스레드가 사용중인 변수를 순간적으로 수정해서 예상치 못한 결과를 얻을 수 있다.




스레드를 제대로 사용하면?

개발 및 유지 보수 비용을 줄이고 복잡한 애플리케이션의 성능을 향상 시킬 수 있다. 비동기적인 일 흐름을 거의 순차적으로 바꿀 수 있어 사람이 일하고 상호작용하는 방식을 모델리 하기 쉬워진다. 꼬인 코드를 새로 작성해 읽기 쉽고 유지보수하기도 쉬운 명료한 코드로 만들 수도 있다.


왠만하면, 자바 애플리케이션에서는 어느 정도는 여러 개의 스레드를 이용한다.

다시말하면, 대부분 자바 프로그램들은 멀티프로세서를 활용하고, 단순한 모델링을 하고, 단순한 비동기 이벤트 처리를 할 수 있으며 더 빨리 반응하는 사용자 인터페이스를 만들 수 있다.




반면에 스레드를 제대로 사용하지 못하면?

개발자라면 대부분 스레드 안전성(thread safety)에 대해 잘 알아야 한다. 같은 코드라도 스레드가 하나일 때는 아무 문제 없지만, 스레드가 여럿일 때는 제대로 동작하지 않는다. 


스레드는 서로 같은 메모리 주소 공간을 공유하고 동시에 실행되기 때문에 다른 스레드가 사용 중일지도 모르는 변수를 읽거나 수정할 수도 있다. 여러 스레드가 같은 변수를 읽고 수정하게 하면 원래 순차적이던 프로그래밍 모델에 비순차적인 요소가 들어가 혼란스럽고 동작 과정을 추론하기 어려워질 수 있다. 다행히 자바에서는 공유 변수 접근을 조율하기 위한 동기화 수단이 제공된다.




프로그래머는 반드시 스레드 안전성 문제를 신경써야 한다. 안전성을 양보할 수 없는 것이다.

멀티스레드 프로그램뿐 아니라 단일 스레드 프로그램도 안전성과 정확성을 유지하도록 작성돼야 한다. 멀티스레드를 사용하면 단일 스레드 프로그램에서 발생하지 않는 추가적인 안전성 위험에 놀출 될 수 있다. 비슷하게 스레드를 사용할 때는 단일 스레드 프로그램에서는 나타나지 않는 추가적인 형태의 활동성(liveness) 장애가 생길 수 있다. 활동성 장애를 일으키는 오류 역시, 초기에 파악하기가 무척 어렵다.

안전성이 "잘못된 일이 생기지 않는다."는 것을 뜻하는 반면,

활동성은 "원하는 일이 결국 일어난다"는 보완적인 목표에 관한 것이다.




'General > Java concurrency in practice' 카테고리의 다른 글

[Java concurrency] Java Concurrency in Practice  (0) 2012.07.08
Posted by croute

댓글을 달아 주세요