여기서 주의해야 할 점이 있는데, ➋와 ➎ 중 어느 것이 먼저 실행될지는 아무도 모른다는 것입니다. 디버거를 실행한 후 중단점을 ➋와 ➎에 모두 걸고 여러 차례 실행해 보세요. ➋와 ➎가 무작위로 실행될 것입니다. 물론 둘 중 하나만 실행되고 있을 수도 있겠지만, 이는 그저 한쪽이 실행 확률이 높을 뿐이며 다른 시스템 환경에서는 다를 수 있습니다. 어쨌든 이론적으로는 ➋와 ➎ 중 어느 것이 먼저 실행되는지 규정된 바가 없습니다.
자, 이제 메인 스레드에서는 ➋가 실행 중이고, 스레드 1이 실행 중입니다. 여러분 프로그램은 동시에 여러 일을 하고 있습니다! ➋와 ➎ 중 어느 것이 실행이 끝나고 다음 줄로 넘어갈지는 아무도 모릅니다.
메인 스레드의 ➋가 먼저 끝났다면 메인 스레드는 ➌을 실행할 차례입니다. ➌의 Join() 함수가 하는 일은 “스레드 1의 일이 모두 끝날 때까지 기다려라.”입니다. 스레드 1은 아직 ➎에 머물러 있습니다. ➏에서 Join()을 실행하고 있는 메인 스레드는 여기서 실행을 일시 정지하고 기다립니다. 이때 우리는 “메인 스레드가 대기 중이다.”라고 표현합니다.
시간이 지나서 스레드 1의 ➎가 모두 끝났습니다. 스레드 1은 실행 지점을 ➏으로 옮깁니다. 더 이상 할 일이 없습니다. 따라서 ThreadProc()의 실행을 모두 끝내고 리턴을 하면 스레드 1은 소멸됩니다.
그림 1-10은 스레드의 일생을 그림으로 표현한 것입니다.
▲ 그림 1-10 스레드의 일생