본문 바로가기

JAVA

[Java] 8-1강 - 멀티스레드 1 (Multithread)

0. Background

1) process

OS는 process를 만듭니다. 

process : program을 실행하기 위한 자원(memory)을 분배

 

2) Thread

process보다 작은 실행 흐름의 최소 단위이다.

1> process는 최소 하나의 thread가 필요합니다. (여러개의 thread가 할당될 수 있다.)

2> process는 여러 개의 thread가 할당될 수 있으며 이를 multi-threaded process라고 합니다.

3) Multitasking

하나의 OS가 여러 process를 실행할 수 있습니다.

 

4) Multithreading

하나의 process가 여러 thread를 만들고 실행

(process를 만드는 것보다 thread를 만드는 것이 가볍다.)

 

1> 장점

[1] resource를 효율적으로 사용한다. (여러 thread가 동시에 다른 일을 해서 자원을 효율적으로 사용 가능하다.)

[2] user에게 빠르게 응답할 수 있다. (여러 user에게 동시에 communicate할 수 있다.)

[3] thread로 업무를 분담하기 때문에 code의 modularity가 가능하다.

 

2> 단점

프로그래머가 multithread 상황을 잘 이해하고 있어야 단점을 보완할 수 있다.

[1] Synchronization : thread의 timing 문제

(A thread reading from memory while another thread writing to the memory.)
[2] Dead-lock : 다른 thread가 hold하고 있는 resource를 서로 request하는 상황 (서로 양보하지 않는다.)

Thread A is holding resource C and requesting resource D, while thread B is holding resource D and requesting resource C.

[3] Inefficiency : thread를 만들었는데 아무 일도 안하는 상황

(A thread may be waiting in idle state although it can work on other tasks.)

 

1. JAVA로 thread 구현

아래 2가지 방법 중 한 가지를 사용한다.

- Thread라는 class를 상속받기 (run 메소드를 override한다.)

- Runnable이라는 interface를 implement (run 메소드를 implment한다.)

 

0) Extending class Thread vs implementing interface Runnable

1) Extending class Thread 

1> getName과 같은 메소드를 그냥 사용할 수 있다.

 

2) implementing interface Runnable

1> static 메소드를 이용해서 getName을 사용한다.

 

3) start 메소드

thread를 시작할 때 부른다.

1> 해당 thread가 OS의 scheduler로 들어간다.

(scheduler : 여러 thread를 보관하다가 실행하고 싶은 thread는 CPU로 이동시킨다.)

2> (scheduler가 thread를 CPU로 보낸 뒤에) thread가 CPU에서 실행됩니다.

 

2. Thread의 start와 run

start()은 호출하는데 run()은 호출하지 않는다.

1) run()만 호출하는 경우

1> call stack

2> 진행 과정

run()이 호출되고 끝나면 다시 main()으로 돌아갑니다.

=> 이는 단순히 run()만 호출할 뿐 새로운 thread를 부르지 않습니다.

 

2) start()를 호출한 뒤, run()을 호출

1> call stack의 변화

2> 진행 과정

- [1] start()를 호출하면, [2] 새로운 call stack을 만듭니다.

- [3] 그리고 run()을 호출하면 새로운 call stack에 run()이 들어갑니다.

=> 따라서 새로운 thread를 만드려면 start()를 호출해야 한다.

 

3> 결론

2개의 thread가 존재하여 독립적으로 각 task를 수행합니다.

- dual core 이상이면, 동시에 각 task를 수행하고

- single core라면, 어떤 thread가 CPU에 얼마나 있을지 scheduler가 결정합니다.

 

3) 2개의 thread가 동시에 실행될 때

1> 어떤 thread가 먼저 끝날 지 모릅니다.

2> main()이 run()보다 먼저 끝나면 calll stack이 사라질 수 있습니다.

=> 모든 thread가 끝날 때 program이 끝나도록 해야 합니다.

 

4) 예시

1> start() 호출했을 때, call stack 확인

2> run() 호출했을 떄, call stack 확인

3. single thread와 multiple thread의 차이

0) concurrent vs simultaneous

concurrent : independent

simultaneous : 동시에 실행되는 것 (한 번에 각 core에 올라가는 것)

1) single thread 

2개의 task를 순차적으로(sequentially) 완료합니다.

 

 

2) multi thread & single core (concurrently run)

CPU에 하나의 task를 오래 올려놓지 않습니다.

조금씩 실행시켜서 사람이 보기에 동시에 실행되는 것처럼 보이게 합니다. (짧게 짧게 실행합니다.)

 

3) multi thread & multi core (simultaneously run)

각 core 별로 task를 수행합니다.

4) Multithreading의 장점

0> Thread.sleep() : 1초간 아무것도 하지 않고 기다리는 것

1> single thread 예시

2> multi thread 예시

multi thread의 경우 user input을 기다리는 동안(A) countdown(B)를 할 수 있습니다.