Join() 메서드의 필요성
Join() 메서드의 필요성을 이해하기 위해 다음 예제를 살펴봅시다. 다음 예제는 Main() 문에서 세 개의 스레드 객체를 실행합니다.
class Program
{
public static void ThreadMethod001()
{
Console.WriteLine("ThreadMethod001() 메서드 호출");
Thread.Sleep(5000);
Console.WriteLine("ThreadMethod001() 메서드 종료");
}
public static void ThreadMethod002()
{
Console.WriteLine("ThreadMethod002() 메서드 호출");
Thread.Sleep(3000);
Console.WriteLine("ThreadMethod002() 메서드 종료");
}
public static void ThreadMethod003()
{
Console.WriteLine("ThreadMethod003() 메서드 호출");
Thread.Sleep(7000);
Console.WriteLine("ThreadMethod003() 메서드 종료");
}
static void Main(string[] args)
{
Console.WriteLine("Main문 시작");
Thread thread001 = new Thread(ThreadMethod001);
Thread thread002 = new Thread(ThreadMethod002);
Thread thread003 = new Thread(ThreadMethod003);
thread001.Start();
thread002.Start();
thread003.Start();
Console.WriteLine("Main문 종료");
}
}
실행 결과
Main문 시작
ThreadMethod001() 메서드 호출
ThreadMethod002() 메서드 호출
Main문 종료
ThreadMethod003() 메서드 호출
ThreadMethod002() 메서드 종료
ThreadMethod001() 메서드 종료
ThreadMethod003() 메서드 종료
실행 결과에서 알 수 있듯이 main() 문이 모든 thread 객체의 실행 또는 작업이 완료될 때까지 기다리지 않습니다. 심지어 thread003 객체는 Main() 문 종료 후 호출되었습니다.
여기서 Main() 문 내부에 있는 thread001, thread002, thread003 객체는 Main() 문의 자식 스레드이며, Main() 문은 기본 스레드입니다. 자식 스레드가 작업을 완료할 때까지 기본 스레드를 종료하지 않으려면 Thread 클래스의 Join() 메서드를 사용해야 합니다.
Join() 메서드
Thread 클래스의 Join() 메서드는 현재 스레드 객체의 작업이 완료되거나 종료될 때까지 기본 스레드의 실행을 대기하도록 합니다. Join() 메서드를 사용하여 동기화를 작업을 수행할 수 있으며, 특정 스레드 객체의 작업이 종료되었는지 확인할 수 있습니다.
Join() 메서드는 오버로드된 세 가지 형태가 존재합니다.
1. Join()
public void Join();
첫 번째 형태는 인수가 없는 Join() 메서드는 현재 스레드 실행을 완료하거나 표준 COM 및 SendMessage 펌핑을 수행하는 동안 작업이 완료될 때까지 기본 스레드의 호출을 차단합니다. 기본 스레드는 현재 스레드의 실행이 완료될 때까지 무한 시간 동안 대기합니다.
COM 및 SendMessage 펌핑은 C#으로 개발된 응용 프로그램에서 마우스 이동/클릭, 키 이벤트, 창 크기 조절과 같은 이벤트를 OS에 요청 및 처리하는 과정이라고 생각하면 됩니다
2. Join(int millisecondsTimeout)
public bool Join(int millisecondsTimeout);
두 번째 형태는 제한 시간을 밀리 초로 설정할 수 있습니다. 현재 스레드 실행이 종료되거나 설정된 시간이 경과할 때까지 기본 스레드의 호출을 차단합니다.
설정한 시간 이내 종료된 경우 true를 반환하고, 시간이 지나도 스레드가 종료되지 않은 경우 false를 반환합니다.
3. Join(Timespan timeout)
public bool Join(TimeSpan timeout);
세 번째 형태는 두 번째 형태와 유사합니다. 차이점은 제한 시간을 TimeSpan으로 설정한다는 것입니다.
Join() 메서드 예제 1.
다음 예제는 스레드 thread002 객체에서 Join() 메서드를 호출합니다. thread002 객체의 작업이 완료되면 기본 스레드가 종료됩니다.
class Program
{
public static void ThreadMethod001()
{
Console.WriteLine("ThreadMethod001() 메서드 호출");
Thread.Sleep(5000);
Console.WriteLine("ThreadMethod001() 메서드 종료");
}
public static void ThreadMethod002()
{
Console.WriteLine("ThreadMethod002() 메서드 호출");
Thread.Sleep(3000);
Console.WriteLine("ThreadMethod002() 메서드 종료");
}
public static void ThreadMethod003()
{
Console.WriteLine("ThreadMethod003() 메서드 호출");
Thread.Sleep(7000);
Console.WriteLine("ThreadMethod003() 메서드 종료");
}
static void Main(string[] args)
{
Console.WriteLine("Main문 시작");
Thread thread001 = new Thread(ThreadMethod001);
Thread thread002 = new Thread(ThreadMethod002);
Thread thread003 = new Thread(ThreadMethod003);
thread001.Start();
thread002.Start();
thread003.Start();
thread002.Join();
Console.WriteLine("Main문 종료");
}
}
실행 결과
Main문 시작
ThreadMethod003() 메서드 호출
ThreadMethod001() 메서드 호출
ThreadMethod002() 메서드 호출
ThreadMethod002() 메서드 종료
Main문 종료
ThreadMethod001() 메서드 종료
ThreadMethod003() 메서드 종료
만약, 모든 스레드 객체의 작업이 완료된 후 기본 스레드가 호출되기를 원한다면, thread001, thread003 객체에도 Join() 메서드를 호출합니다.
Join() 메서드 예제 2.
다음 예제는 스레드 thread001 객체에서 밀리초를 인수로 가지는 Join() 메서드를 호출합니다. thread001 객체가 작업을 완료할 때까지 3초 기다립니다.
class Program
{
public static void ThreadMethod001()
{
Console.WriteLine("ThreadMethod001() 메서드 호출");
Thread.Sleep(5000);
Console.WriteLine("ThreadMethod001() 메서드 종료");
}
static void Main(string[] args)
{
Console.WriteLine("Main문 시작");
Thread thread001 = new Thread(ThreadMethod001);
thread001.Start();
if(thread001.Join(2000))
{
Console.WriteLine("2초 이내 작업 완료");
} else
{
Console.WriteLine("2초 경과");
}
Console.WriteLine("Main문 종료");
}
}
실행 결과
Main문 시작
ThreadMethod001() 메서드 호출
2초 경과
Main문 종료
ThreadMethod001() 메서드 종료
thread001 객체의 작업이 2초 이내 완료되지 않았으므로 기본 스레드가 호출됩니다. 따라서, 기본 스레드는 thread001 객체의 작업을 기다리지 않고 호출됩니다.
정리
- 기본 스레드가 자식 스레드보다 먼저 종료될 수 있습니다.
- 기본 스레드의 종료를 막기 위해 Join() 메서드를 호출합니다.
- Join() 메서드는 현재 스레드 객체의 작업이 완료될 때까지 기본 스레드를 대기시킵니다.
'C#' 카테고리의 다른 글
[C#]예외 처리(Exception Handling) (0) | 2022.06.26 |
---|---|
[C#]타입 변환 및 타입 캐스팅(Type Conversion and Type Casting) (0) | 2022.06.21 |
[C#]스레드 상태 확인 (0) | 2022.06.06 |
[C#]파일 존재 여부 확인 (0) | 2022.06.06 |
[C#]base 키워드 (0) | 2022.06.05 |
댓글