Thread(스레드)
프로세스의 자원을 이용해 작업을 수행하는 실행 단위
스레드 구현
구현 방법으로는 아래 두 개의 방법이 있으며 큰 차이는 없으나 Thread 클래스를 상속 받으면 다른 클래스를 상속 받을 수 없기 떄문에 Runnable 방법을 권장한다.
Thread 클래스를 상속받아 구현
Runnable 인터페이스를 구현
스레드 실행
생성된 스레드를 실행하기 위해서는 run()
이 아닌 start()
메서드를 호출해야 한다.
start()
메서드가 호출되어도 해당 스레드에서 바로 실행 되는 것이 아니기 때문에, 스레드 스케줄러에 의해 대기 상태가 되고 대기 상태에 있는 스레드는 스레드 스케줄러에 의해 실행된다.
한 번 실행된 스레드는 다시 실행할 수 없으며 두 번 이상 실행하게 되면 IllegalThreadStateException
예외가 발생한다.
start()
vs run()
start()
vs run()
run()
: 생성된 스레드를 실행시키는 것이 아니라 단순히 클래스에 선언된 메서드를 호출start()
: 새로운 스레드가 작업을 실행하는데 필요한call stack
을 생성하고 생성된call stack
에run()
메서드를 실행
호출 스택을 강제로 출력하는 코드 사용하여 결과를 확인해보면 start()
메서드를 호출한 경우 main 스레드와 별도의 스레드가 생성되어 실행되는 것을 확인할 수 있다.
run()
을 통해 실행하게 되면 단순히 메서드를 호출하는 것이기 때문에 main 스레드에서 run()
메서드가 실행되는 것을 확인할 수 있다.
모든 스레드는 작업을 수행하기 위해 자신만의 call stack
이 필요한데, 새로운 스레드를 생성하고 실행하면 아래와 같은 순서로 실행된다.
새로운 스레드가 생성되고
run()
메서드가 호출되어 새로운call stack
이 생성run()
메서드가 종료되면서 해당 스택이 비워지게 되면서, 해당 스레드는 종료되고call stack
도 소멸
결국 main 스레드에서 start()
메서드를 호출하면 아래의 순서로 실행된다.
main 메서드에서 구현한 스레드의
start()
메서드를 호출start()
는 새로운 스레드를 생성하고, 스레드가 작업하는데 사용될call stack
을 생성생성된 스레드가 새로 생성된
call stack
에run()
메서드를 호출스케줄러에 의해 번갈아 가며 작업 수행
스레드 우선순위
스레드는 priority
라는 속성(멤버변수)를 가지고 있으며 이 속성은 스레드의 우선순위를 나타낸다.
스레드의 우선순위는 1 ~ 10 사이의 값을 가질 수 있으며 기본값은 5
OS마다 다른 방식으로 스케쥴링하기 때문에 실행 결과는 정확히 알 수 없음
실행제어
멀티 스레드 프로그래밍이 어려운 이유는 동기화(synchronization)와 스케줄링(scheduling) 때문이다. 효율적인 멀티스레드 관리를 위해서는 우선 관련 메서드와 스레드의 상태를 이해해야 한다.
스케줄링 메서드
static void sleep(long millis)
지정된 시간 동안 스레드 일시정지
void join(), void join(long mills)
지정된 시간동안 스레드가 실행되도록 함, 지정된 시간이 지나거나 작업이 종료되면 join()
을 호출한 스레드로 다시 돌아와 실행
void interrupt()
sleep()
/join()
에 의해 일시정지 상태인 스레드를 깨워 실행대기 상태로 만듬
void stop()
스레드를 강제로 종료
void yield()
다른 스레드에게 실행 양보하고, 호출한 스레드는 실행대기 상태로 변경
void suspend()
스레드를 일시정지 상태로 만듬, resume()
을 호출할 때까지 실행되지 않음
void resume()
suspend()
에 의해 일시정지 상태인 스레드를 다시 실행대기 상태로 만듬
** resume()
, stop()
, suspend()
는 스레드를 교착상태(dead-lock)로 만들기 쉽기 때문에 deprecated 됨
스레드의 상태
NEW
스레드가 생성되고 아직 start()
가 호출되지 않은 상태
RUNNABLE
실행 중 또는 실행 가능한 상태
BLOCKED
동기화 블럭에 의해 일시정지된 상태(lock
이 풀릴 때까지 기다리는 상태)
WAITING / TIMED_WAITING
스레드의 작업이 종료되지는 않았지만 실행가능하지 않은(unrunnable
) 일시정지 상태(TIMED_WAITING
은 일시정지시간이 지정된 경우
TERMINATED
스레드의 작업이 종료된 상태
스레드 생성 - 소멸 과정
스레드 생성하고
start()
호출하여 실행 대기열에 저장되어 실행 대기 상태로 만듬실행대기열은 큐(queue)와 같은 구조로 먼저 실행대기열에 들어온 스레드가 먼저 실행됨
실행 대기열에 있다가 차례가 되면 실행상태로 변경
주어진 실행시간이 다되거나
yield()
를 만나면 실행대기상태가 되고 다시 실행대기열에 들어감실행 중
suspend()
,sleep()
,join()
,wait()
,I/O block
의해 일시정지 상태가 될 수 있음지정된 일시정지시간이 다 되거나
time-out()
,notify()
,resume()
,interrupt()
등의 메서드를 호출하면 다시 실행대기상태가 됨실행을 모두 마치거나
stop()
을 호출하면 종료상태가 됨
참고자료
Last updated
Was this helpful?