/ JAVA

쓰레드- start()와 run() (2)

쓰레드를 구현하고 나면서 드는 생각이 있었다.
쓰레드를 실행시킬 때 run()과 start()를 구분해서 사용할까?

자세히 알아보자

//구현
class MyThread01 extends Thread {
	@Override
	public void run() {
		System.out.print(getName()); 
	}
}
//실행
public class Ex01 {
	public static void main(String[] args) {
		MyThread01 mt01 = new MyThread01();
		// run을 호출(XXX) start사용	
		mt01.start(); 
  1. 간단히 말해서
    run() - main메서드에서 run()만을 호출하는 것은 생성된 쓰레드를 실행시키는 것이 아니라 단순히 클래스에 선언된 메서드를 호출하는 것일 뿐이다.
    반면에
    start() - 새로운 쓰레드가 작업을 실행하는데 필요한 호출스택(call stack)을 생성한 다음에 run()을 호출해서 생성된 호출스택에 run()이 첫 번째로 올라가게 한다.

  2. main 또한 쓰레드이다.
    프로그램의 시작과 함께 생성되는 하나의 쓰레드가 main메서드를 호출하여 작업이 수행되도록 하는데
    1) 그렇다면 호출스택에 main이 가장 아래 깔리게 된다.
    2) 이후 start()가 호출되어 main 위로 올라가고 새로운 쓰레드를 생성하고, 쓰레드가 작업하는데 사용될 호출스택을 새로 생성한다.
    3) 그리하여 그 호출스택에 run()이 호출되어, 쓰레드가 독립된 공간에서 작업을 수행한다. start는 할일을 다해서 종료됨.
    4) 이렇게 생긴 main의 호출스택과 새로 생성된 run의 호출스택 두개가 남게된다.
    물론, main쓰레드 호출스택은 run쓰레드의 종료와 상관없이 임무를 마치면 혼자 사라진다.

  3. 일부러 새로 생성한 쓰레드에서 예외를 발생시키고 예외가 발생한 당시의 호출스택을 출력하는 예제로 쓰레드 간의 영향을 확인해보자.

결과 ex_screenshot 호출스택
|throwException
|run

호출스택의 첫 번째 메서드가 main메서드가 아닌 run메서드인 것을 확인할 수 있다. 즉, 한 쓰레드가 예외를 발생해서 종료되어도 다른 쓰레드의 실행에는 영향을 미치지 않는다.

start()로 쓰레드를 생성함과 동시에 호출스택을 생성해 내는것을 한번 더 기억하자.

4. 그렇다면 호출스택을 생성하지 않는 run()으로 쓰레드를 바로 실행하면 어떻게 될까?
호출스택
|throwException
|run
|main

앞선 그림과 다르게 main쓰레드가 함께 출력됐다. 즉, main쓰레드의 호출스택에서 run()이 실행됐음을 알 수 있다.