
Thread는 객체를 생성하고, start() 메서드를 호출하면 실행 대기 상태가 된다.
스케줄링이 되지 않아서 실행을 기다리고 있는 상태
실행 대기 상태에 있는 스레드 중에서 스레드 스케줄링으로 선택된 스레드가 CPU를 점유하여 run() 메서드를 실행한다.
실행 상태의 스레드는 run() 메서드를 모두 실행하기 전에 스레드 스케쥴링에 의해 다시 실행 대기 상태로 돌아갈 수 있다.
다시 실행 대기 상태로 돌아간다면 실행 대기 상태에 있는 다른 스레드가 선택되어 실행 상태로 변하게 된다.
이렇게 스레드는 실행 대기 상태와 실행 상태를 번갈아가며 run()메서드를 실행한다.
실행 중인 스레드는 sleep( ), wait( ) 메서드 혹은 입출력 요청에 의해 일시 정지 상태(Blocked)로 가기도 한다.
일시 정지 상태에서는 바로 실행 상태로 돌아갈 수 없고, 실행 대기 상태로 간 후 실행 상태로 가야 한다.
interrupt( ), notify( ), notifyAll( ) 메서드를 통해 일시 정지 상태의 스레드를 실행 대기 상태로 만들 수 있다.
(경우에 따라 실행 상태에서 실행 대기 상태로 가지 않을 수 있다.)
상태변경을 하면서 실행 상태에서 run()메서드가 종료되면 이를 종료 상태라 한다.
실행 중인 스레드의 상태를 변경하는 것을 스레드 상태 제어라 한다.
멀티 스레드 프로그램을 만들기 위해서는 정교한 스레드 상태 제어가 필요하다.
sleep메서드는 Thread의 클래스 메서드로 파라미터에 입력한 수의 밀리세컨드 동안 스레드를 멈춘다.
sleep() 메서드를 실행하면 실행한 스레드는 일시 정지 상태로 전환되며, 파라미터로 전달된 시간이 경과 하거나 interrupt() 메서드를 호출한 경우 다시 실행 대기 상태로 복귀한다.
interrupt() 메서드는 일시 정지 상태인 스레드를 실행 대기 상태로 복귀시킨다.
sleep(), wait(), join() 메서드에 의해 일시 정지된 스레드들은 각각 해당 메서드에서 정지한다.
정지 중인 스레드가 아닌 다른 스레드에서 interrupt()를 호출하여 정지 상태를 실행 대기 상태로 전환한다.
yield() 메서드는 다른 스레드에 자원을 양보한다.
yield()를 호출하면 남은 자원은 다른 스레드에 양보하고 호출된 시점으로 부터 실행 대기 상태로 전환된다.
join() 메서드는 특정 스레드가 작업하는 동안에 자신을 일시 정지 상태로 전환하는 메서드로, 다른 메서드가 작업이 끝날 때 까지 기다린다.
join() 메서드는 파라미터로 밀리세컨드를 받으며 시간이 다 지나거나 interrupt() 메서드가 호출되거나 스레드.join() 으로 호출한 스레드가 모든 작업을 마치면 다시 실행 대기 상태로 복귀한다.
join() 메서드는 sleep()과 유사하지만 join()은 특정 스레드에 대해 동작하며 sleep은 Thread클래스를 정지시킨다.
wait()와 notify() 메서드는 두 스레드가 교대로 작업을 처리해야 할 때 사용하는 메서드이다.
두 스레드 A와 B가 하나의 공유 객체를 두고 협업을 하는 상황이라면,
A가 먼저 작업을 한 뒤 완료하면, B와 교대하기 위해 notify() 메서드를 호출한다.
notify() 메서드가 호출되면 B는 실행 대기 상태로 전환되며, A는 wait() 메서드를 호출하여 자기 자신을 정지 상태로 만든다.