메인 스레드(Main thread)

자바 어플리케이션에서 main() 메서드는 프로그램의 시작점 입니다.
그리고 main() 메서드 또한 스레드에 의해 실행되는데 이 스레드를 main 스레드라 합니다.

모든 자바 어플리케이션은 JVM에서 동작하는데 main() 메서드가 있는 클래스를 찾고 메인 스레드를 생성한 후 메인 스레드에서 main() 메서드를 실행하는 것입니다.

 

 

 

 (평소에 공부 또는 테스트용 로직으로 main() 메서드에서 시작해서 main() 메서드에서 종료되는 어플리케이션의 처리 흐름)

 

 

자바 어플리케이션 자체는 운영체제에게 자원을 할당받은 프로세스 입니다.
컴파일된 자바 클래스는 JVM 위에서 동작하죠.
JVM은 프로그램의 시작점인 main() 메서드를 찾아서 메인 스레드를 생성하고 메인 스레드의 run() 메서드를 통해 해당 main() 메서드를 실행합니다.
이때 main(String[] args) 매개변수인 String 배열에 명령행에서 입력한 파라미터를 넣어 호출하는 것입니다.

이 시점에서 스레드는 메인 스레드 하나이고 당연히 처리 흐름도 하나입니다.

※데몬 스레드는 다른 스레드에게 도움을 주는 스레드인데 대표적인 데몬스레드는 가비지 컬렉터입니다.
(JVM 시작시 데몬스레드도 실행 되지만 로직을 실행하는 스레드는 이시점에서 메인 스레드 하나이므로 처음 시작시 스레드는 일단 하나다 라고 알아두세요.)


스레드는 생성 후 start() 메서드를 호출해야만 실행되며 스레드의 run() 메서드에서 아무 일도 하지 않는 경우 생성 되자마자 종료됩니다.

 

 

스레드의 생성 및 실행

스레드의 생성 방법은 크게 두가지가 있습니다.
첫번째는 Thread 를 상속하는 방법.
두번째는 Runnable 인터페이스를 구현한 후 Thread 객체를 통해 실행하는 방법입니다.


Thread를 상속하여 생성 후 실행하는 방법
1.Thread를 상속하는 클래스를 만든다.
2.실행할 로직을 run() 메서드를 오버라이딩 하여 구현한다.
3.만든 Thread 클래스로 Thread 객체를 생성한 후 start() 메서드를 통해 실행

 

Tread_1.java

1
2
3
4
5
6
7
8
9
10
11
public class Thread_1 {
 
     public static void main(String[] args) {
 
           MyThread myThread = new MyThread();
           myThread.start();
 
           System.out.println("main 스레드 종료");
     }
 
}
cs

 

 

MyThread.java

1
2
3
4
5
6
7
8
9
10
11
12
public class MyThread extends Thread{
 
     @Override
     public void run() {
           for(int i = 1; i < 300; i++){
                System.out.println("새로운 스레드 ");
           }
 
           System.out.println("myThread 종료");
     }
 
}
cs

 

결과를 예상해보세요.

결과
1
2
3
4
5
6
7
8
9
새로운 스레드
새로운 스레드
main 스레드 종료
새로운 스레드
새로운 스레드
새로운 스레드
새로운 스레드
....생략...
myThread 종료 
cs

 

결과는 컴퓨터 사양이나 기타 환경에 따라 달라질 수 있습니다.
이유는 스레드에 대한 스케줄링은 스레드 스케줄러가 하기 때문이지요.
스레드 스케줄러에 대해서는 이후에 따로 글을 작성하도록 하겠습니다.

하지만 대부분 저와 비슷한 결과가 나올것입니다.
새로운 스레드가 시작되면서 처리 흐름은 두 개가 되었고 메인 스레드가 종료되어도
새로 생성한 스레드의 흐름이 계속되었기 때문에 어플리케이션이 종료되지 않았습니다.

myThread 스레드가 종료되어야 비로소 어플리케이션이 종료되는 것입니다.

 

 

 

 

(멀티 스레드 실행)

메인스레드가 시작되면서 메인스레드의 run() 메서드 안에서 Thread_1의 main()메서드를 실행시켰고
MyThread 객체를 만든 후 (이때 MyThread는 Thread를 상속받은 스레드 객체) start() 메서드를 통해 새로운 스레드가 시작되었습니다.
스레드가 시작되면 myThread의 run()메서드가 실행됩니다. 
myThread는 다른 객체의 메서드를 실행하지 않고 run() 메서드 안에서 모든 로직을 처리하였습니다.

(System.out 도 객체지만 생략)


질문) start() 메서드와 run() 메서드는 무슨 차이인가요? 왜 굳이 start()를 실행해야 하죠?
이후 포스팅 글에서 나오겠지만 start() 메서드는 정확히는 현재 스레드를 스레드풀에 등록하는 것입니다.
스레드 풀에 등록된 스레드는 쉬고 있다가 스레드 스케줄러가 "이제 네가 실행될 차례야" 라고 했을때 그 스레드의 run()메서드가 실행하는 것입니다.
그렇기 때문에 main() 메서드에서 myThread.run()을 호출했다면 단순한 객체의 run() 메서드를 호출한것으로 판단해 새로운 흐름이 생기지 않고
반복 출력 후 myThread 종료 - > miain 스레드 종료 순으로 로직의 흐름이 진행 됩니다.

 

 

 

 

이전글

[Java]스레드(Thread) - [1] 스레드란?

 

 

 

블로그 이미지

도로락

IT, 프로그래밍, 컴퓨터 활용 정보 등을 위한 블로그

,