Clean Code that Works.

  자바에서의 쓰레드는 『프로그램을 실행하는 주체』라고 할 수 있습니다. 그러나 운영체제(OS)의 프로세스(process)도 프로그램을 실행하는 주체라고 말할 수 있습니다. 이번 글에서는 프로세스와 쓰레드의 차이점에 대해서 이야기하겠습니다.

  프로세스와 쓰레드의 관계는 플랫폼의 차이점(OS나 하드웨어의 차이)에 의해서 크게 달라집니다. 플랫폼이 같아도 자바 가상 머신(Java Virtual Machine, JVM)의 구현 방법에 따라 프로세스와 쓰레드의 관계는 달라집니다. 그러나 일반적으로는 하나의 프로세스 안에서 복수의 쓰레드가 구축된다고 해도 맞는 말이 되겠지요.

  쓰레드는 메모리를 공유한다.

  프로세스와 쓰레드의 가장 큰 차이점은 메모리 공유의 유무입니다.

  프로세스는 각각 독립된 메모리 공간을 가지고 있는 것이 보통입니다. 어떤 프로세스가 다른 프로세스의 메모리를 마음대로 읽는다든지 메모리에 쓴다든지 하는 것은 아닙니다. 프로세스의 메모리 공간은 각각 독립되어있기 때문에 어던 프로세스가 다른 프로세스 때문에 망가질 위험이 없는 겂입니다.

  쓰레드는 메모리를 공유합니다.[주] 하나의 쓰레드가 메모리 상에 정보를 쓰고 그것을 다른 쓰레드가 읽는 것은 자주 일어나는 일입니다. 『메모리를 공유하고 있다』라는 것은 자바에서 말하면 『인스턴스를 공유하고 있다』라는 의미입니다. 자바의 인스턴스는 메모리 상에 있고 복수의 쓰레드가 그 인스턴스를 읽고 쓸 수 있도록 되어 있습니다.

[주] 자바의 메모리 모델에서는 메인 메모리와 워킹 메모리라는 두 종류의 메모리가 등장합니다. 이 때에 쓰레드가 공유하는 것은 메인 메모리 쪽입니다.

  쓰레드가 메모리를 공유하고 있기 때문에 쓰레드 간의 통신은 매우 자연스럽고 간단히 실현될 수 있습니다. 어떤 쓰레드가 인스턴스에 정보를 써서 다른 쓰레드가 그 인스턴스에서 정보를 읽으면 되는 것입니다. 한편 같은 인스턴스에 복수의 쓰레드에서 접근하기 때문에 배타 제어를 바르게 해야 합니다.

  쓰레드는 콘텍스트스위치(context-swith)가 가볍다.

  프로세스와 쓰레드의 또 하나의 차이점은 콘텍스트 스위치의 무게입니다.

  동작중인 프로세스가 바뀔 대 프로세스는 현재 자기의 상태(콘텍스트 정보)를 일단 보존합니다. 그리고 새롭게 동작 개시하는 프로세스는 이전에 보전해 두었던 자신의 콘텍스트 정보를 다시 복구합니다. 이와 같은 정보의 바꿈(context-switch)에는 시간이 걸립니다.
 
  동작중인 쓰레드가 바뀔 때 쓰레드는 프로세스와 같이 콘텍스트 스위치를 행합니다. 그러나 쓰레드가 관리하고 있는 콘텍스트 정보는 프로세스보다도 적기 때문에[주] 쓰레드의 콘텍스트 스위치는 프로그램의 콘텍스트 스위치보다도 가볍게 행해지는 것이 보통입니다.

[주] 이것은 어디까지나 일반적인 이야기 입니다. 쓰레드와 프로세스의 실제의 관계는 자바 실행 처리계의 구현에 크게 의존합니다.

  그러므로 빽빽히 연달아 쉬고 있는 복수의 작업을 행하는 경우에는 프로세스보다도 쓰레드쪽이 좋은 경우가 많이 있겠지요.
- Java언어로 배우는 디자인 패턴 입문 -




이 일은 해두어야 해요

문맥 : 쓰레드(Client)가 인스턴스(Host)의 메소드를 호출하고 있다고 합시다.

문제 : 메소드의 처리가 끝나기까지 Host에서 제어가 되돌아오지 않습니다. 메소드의 처리에 시간이 걸리면 응답성이 저하됩니다.

해결법
  Host 중에 새로운 쓰레드를 기동합시다. 그리고 메소드가 해야 할 실제의 처리는 이 새로운 쓰레드에 맡기는 것입니다. 이것으로 Clinet 쓰레드는 곧장 다음의 처리로 넘어 갈 수 있습니다. 이렇게 되면 Client 코드는 그대로 있고 응답성을 높일 수 있습니다.

구현
  자바에서는 손쉽게 쓰레드를 기동하기 위해서 익명 내부 클래스를 이용할 수 있습니다.
  new Thread() {
     public void run() {
       helper.handle(count, c);
     }
  }.start();

관련
  쓰레드의 기동에 걸리는 시간을 줄이고 싶을 때에는 Work Thread 패턴을 사용합니다.
  처리의 결과를 Client에 되돌리고 싶을 때에는 Future 패턴을 사용합니다.

- Java언어로 배우는 디자인 패턴 입문 -

EXEC SP_RENAME '테이블명.[수정할컬럼명]', '수정될 이름', 'COLUMN'

실행 시켰을 시
"주의: 개체 이름 부분을 변경하면 스크립트 및 저장 프로시저를 손상시킬 수 있습니다."

2-2)컬럼 타입 변경

age 칼럼을 int에서 varchar(3)으로 변경

alter table abc alter column age varchar(3)

b) age칼럼을 varchar(3)에서 int not null로 변경

alter table abc alter column age int not null

2-3)칼럼, 제약 제거

alter table abc drop constraint df_addr

b) alter table abc drop constraint df_addr

b) addr칼럼 varchar(10)에서 nvarchar(10)으로 변경가능

alter talbe abc alter column addr nvarchar(10) not null

c)addr칼럼 제거

alter table abc drop column addr




 

없애려고 해도 없어지지 않아

문맥 : 복수의 쓰레드가 인스턴스를 공유하고 있지만 인스턴스의 상태가 변화하는 것은 아닙니다.

문제 : Single Threaded Execution 패턴을 사용하면 스루풋이 떨어져버립니다.

해결법
  인스턴스가 만들어진 후 상태가 변화하는 것이 아니라면 Single Threaded Execution 패턴을 사용하는 것은 그만둡시다. 실수로 상태가 변화하는 코드를 쓰지 않도록 하기 위해 쓰레드가 필드를 변경하지 못하도록 합니다. 또 인스턴스의 상태를 변경하는 메소드(setter)가 있으면 소거합니다. 인스턴스의 상태를 알아보는 메소드(getter)는 있어도 상관없습니다.
  이것이 Immutable 패턴입니다. Immutable 패턴을 사용하면 스루풋은 향상됩니다. 그러나 불변성(immutability)을 계속 보유하는 것은 곤란합니다. 문서에 그 클래스가 immutable인 것을 확실히 알아둡시다.

구현
  자바에서는 필드를 은폐하기 위해 private를 사용합니다. 또한 변경할 수 없도록 하기 위해 final을 사용합니다.

관련
  복수의 쓰레드를 배타 제어할 때에는 Single Threaded Execution 패턴을 사용합니다.
  변경하는 쓰레드가 참조하는 쓰레드의 수보다 적을 때에는 Read-Write Lock 패턴을 사용 합니다.

- Java언어로 배우는 디자인 패턴 입문 -